Compare commits
787 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c2e5e45c84 | |||
| 014236c861 | |||
| 610fd7561b | |||
| d6f4480a4f | |||
| 28a6ac09ad | |||
| 86e4d24476 | |||
| 913a697ab2 | |||
| ebef2b1e44 | |||
| a61457b422 | |||
| 8f7f1135df | |||
| 89612c10c9 | |||
| d55bfb32f1 | |||
| d2b72cf496 | |||
| 8d90fffd46 | |||
| b84af27a86 | |||
| b45f28f3e9 | |||
| bfa1b5656a | |||
| 47f946cd65 | |||
| 970e7bfcda | |||
| a81c7a7cd6 | |||
| b0e1bd239f | |||
| 53ca41717a | |||
| 6a5bee0cdd | |||
| fd3ae51f83 | |||
| 5e5954a808 | |||
| add8540909 | |||
| 06a302aed0 | |||
| 147432d38d | |||
| 2a003ff72b | |||
| 8660d3324d | |||
| 6c59b73ae5 | |||
| 80218c1eca | |||
| f24d96d59f | |||
| d14bd49f46 | |||
| 1a692a0873 | |||
| 631a1a4ddc | |||
| 57df7601d9 | |||
| f7650000aa | |||
| 6f93c2d9b2 | |||
| 1654764968 | |||
| 1a1b8416e2 | |||
| 36c66d52a6 | |||
| 68fe43d488 | |||
| 877b9ee23b | |||
| 80ff93beeb | |||
| b9ddd2812b | |||
| ba54b56de4 | |||
| 85be67bc2d | |||
| ae20e01d2c | |||
| d094e8c3fc | |||
| f009fe1f63 | |||
| 2007fe5f49 | |||
| 84989ffa04 | |||
| 31b629a19c | |||
| e762d9e274 | |||
| 6833267b19 | |||
| 05f2833388 | |||
| 0d026ef18d | |||
| b756d93891 | |||
| f54513586d | |||
| 6c519c237e | |||
| 4ffde4db98 | |||
| 41847d31e7 | |||
| 24ce25bb5c | |||
| e051b69e80 | |||
| 59283d1164 | |||
| 0de32a5edc | |||
| 4f80066dcb | |||
| 04ddc8003f | |||
| 3213f98d66 | |||
| 1f16f85c51 | |||
| c03cb3a11c | |||
| 62e29a6546 | |||
| 3574b065d6 | |||
| c0c47f41be | |||
| 37761d580f | |||
| e075c8e691 | |||
| 0c61ca1a6b | |||
| 1846fa1f54 | |||
| 579ce20cad | |||
| 12e4bcba5d | |||
| b4f57dee3b | |||
| f11673ae3f | |||
| a27af7dd7e | |||
| 2b26a3cc14 | |||
| 47c4849694 | |||
| 30a4adf331 | |||
| 117a721166 | |||
| 1a219e62ba | |||
| c8d54b324b | |||
| 0ac2971fc1 | |||
| 348a40201b | |||
| 9f20ddc800 | |||
| 6f1cc2c1e5 | |||
| 601cd95277 | |||
| 8e9ce59ef2 | |||
| d76ef8e3cf | |||
| c19ffafd8d | |||
| 996a99ad75 | |||
| affb926d44 | |||
| c506e534aa | |||
| 9994315070 | |||
| 4f0d89ef8b | |||
| aab984618d | |||
| 8b662bc6b5 | |||
| 03ce7a8db3 | |||
| 033e7928b5 | |||
| b095f2a158 | |||
| 196c0e0ebc | |||
| 8ab309630b | |||
| 42bac47a71 | |||
| 3bc4de2236 | |||
| a6e4b45a38 | |||
| 28e97ccaf2 | |||
| 255781c029 | |||
| 7f5635ea8c | |||
| 4f18ec726c | |||
| 263622d628 | |||
| 1dfd2443ac | |||
| 881bd53f60 | |||
| ec4404b1ba | |||
| badaeac81f | |||
| 618d5ddaff | |||
| 4ed74af868 | |||
| 123d9af7d0 | |||
| 4f17b30915 | |||
| 1fc265b0aa | |||
| afae9b8d17 | |||
| 481be44879 | |||
| b8530b0f0b | |||
| 69de79684f | |||
| 6e6fd057b5 | |||
| 4b0ebf2b80 | |||
| ee82c32119 | |||
| 3fe6731035 | |||
| 1c3f3b5705 | |||
| def1ccffc4 | |||
| fa2e531343 | |||
| 814ddbc6cc | |||
| 267e8dcfb6 | |||
| 49ec1561f8 | |||
| e2dc612153 | |||
| 8f225431fe | |||
| 194be5e0b7 | |||
| 6788a05dd1 | |||
| 6a7066ac2f | |||
| ec5ff4e973 | |||
| fe6d460531 | |||
| 9cb97af10f | |||
| 1c784eea3d | |||
| 59dd33a461 | |||
| 97ebd912dc | |||
| 742fcc060c | |||
| 3ad5cb8a23 | |||
| 0d1f12e31a | |||
| a8ddf8f66d | |||
| f7a9c0a248 | |||
| 190badb395 | |||
| 3d91ab6c31 | |||
| c15b8d71bc | |||
| 5a707dba8a | |||
| ffd2fcde6b | |||
| 8e4056c1e4 | |||
| 1554e2b135 | |||
| 4715cbb70d | |||
| fd1611079a | |||
| 8edc03df64 | |||
| 9f5c0af5b8 | |||
| 6d6eeba5d5 | |||
| 5dfb64ef71 | |||
| e5bda7add7 | |||
| 77f9b336bd | |||
| cf930d0dde | |||
| f01c94e8bc | |||
| 0d774527b4 | |||
| 58ba9496d0 | |||
| 1993e94e53 | |||
| 3bcc06ed09 | |||
| 2f6ce88e28 | |||
| cd1dec9fc7 | |||
| 05872d7650 | |||
| 1dcee2ffa2 | |||
| 5f622efb77 | |||
| 52e8326d54 | |||
| 436532bed7 | |||
| d15e789200 | |||
| 98942f5528 | |||
| c7c21dc122 | |||
| 4500c1d1a4 | |||
| b8b983dded | |||
| d6a6673971 | |||
| 0580fe8db8 | |||
| c727e24138 | |||
| b83698ebf5 | |||
| 3fbbaa5130 | |||
| 2f48b840ae | |||
| efdee11d5a | |||
| 4c87e11aeb | |||
| e881e008b8 | |||
| 1b2837915d | |||
| d076a6724f | |||
| 386af71c39 | |||
| 49f277192c | |||
| 5974a6276b | |||
| e06a390771 | |||
| b34e204676 | |||
| 755d990dfd | |||
| 7185358b98 | |||
| 3843ec1e02 | |||
| cfc5631d5d | |||
| e64555aca0 | |||
| ef52ebb529 | |||
| c98136ca4f | |||
| 65f44d24ca | |||
| 44f20782fd | |||
| 9b1d76a5d0 | |||
| 21b5074ce8 | |||
| 0b8825fecb | |||
| 3d3c20e507 | |||
| 67a282f19f | |||
| 92023b533a | |||
| c1d14c150e | |||
| aa656c74d5 | |||
| e39b7ffe30 | |||
| 1897148abc | |||
| b76118802a | |||
| 8266aa3343 | |||
| ab0c349261 | |||
| d5e0e66426 | |||
| c5b3107f83 | |||
| 1a0a64e4de | |||
| 6bd9805bcc | |||
| f74c2af65c | |||
| 9531bdf674 | |||
| 76e705e7ee | |||
| d35211328e | |||
| b7bbd81dda | |||
| 9836dd5d10 | |||
| 2109ad320d | |||
| c026121c0e | |||
| ee0c87f7b1 | |||
| 709fb93a22 | |||
| b38cd0a48d | |||
| 264435c32d | |||
| c285929ad3 | |||
| 1cbea8157d | |||
| 0a10334f1b | |||
| f0d5a6ebac | |||
| db7086b5e6 | |||
| 0e92280b33 | |||
| 0d7255158a | |||
| 33564b68dd | |||
| ba942b952a | |||
| bd7f28896e | |||
| 18fe124696 | |||
| ea3a3b6e1c | |||
| e6c06aacff | |||
| 1aee92cd5c | |||
| 40c4cad491 | |||
| 013d46fb02 | |||
| f0f465411f | |||
| 32ce83475d | |||
| ec0d3f5b5d | |||
| 75294b9146 | |||
| 26a0eb68ef | |||
| b983e29fb0 | |||
| 68dadabc29 | |||
| ed9fd3f0e0 | |||
| fa9573436a | |||
| 6d2058c3b7 | |||
| 0d7f93b877 | |||
| f022c9d510 | |||
| 5964a06386 | |||
| f14dc4a4e9 | |||
| fd56e2534c | |||
| 08962a74ab | |||
| f850d36c52 | |||
| c5fb161477 | |||
| bfc2fab33f | |||
| ec9d6c4fd2 | |||
| 6135d61e3d | |||
| a677242a2c | |||
| 6602f30112 | |||
| a4b8dc18c1 | |||
| c0d4741f88 | |||
| b33718180c | |||
| 3872393b29 | |||
| 1d72a7df99 | |||
| 5455908772 | |||
| 8882192fac | |||
| 7b77491c06 | |||
| 20bf214d6e | |||
| 8ab3e63aeb | |||
| 0dc03214c5 | |||
| 362e98b43d | |||
| 193e085cf0 | |||
| e0df2a342b | |||
| ba19ccac43 | |||
| d7261b7a78 | |||
| 0d80173efd | |||
| 930f07d15e | |||
| 66df7389d2 | |||
| c7bf0b6ddd | |||
| 0bc361adeb | |||
| 4fff523a6d | |||
| 67e09fb342 | |||
| c360806f47 | |||
| 7b74b73b08 | |||
| e9a851c0d4 | |||
| b13b169149 | |||
| 455329a745 | |||
| a68b76c8b4 | |||
| 96e3899216 | |||
| 771ab5ea9a | |||
| 3c87e6b270 | |||
| 6d8afec510 | |||
| 89e25657d8 | |||
| 29387f1fcf | |||
| 58e885c052 | |||
| 984dfcd7e1 | |||
| 3785479086 | |||
| 8ed280907c | |||
| d742671205 | |||
| 87e72c28a4 | |||
| 4dee357362 | |||
| 431f4b9b0d | |||
| dd5b7825d5 | |||
| 02bc48925a | |||
| 4eb505755e | |||
| 83e94a70ea | |||
| 8a150b27c3 | |||
| 1a51451ec2 | |||
| 41e51bfb77 | |||
| 7e1d9bc768 | |||
| ba065ec1d8 | |||
| fe057a91c8 | |||
| d2c36eefc9 | |||
| 28d56bab04 | |||
| 2500eff90d | |||
| 153446b3a1 | |||
| 391f5caaa2 | |||
| cc0df92444 | |||
| 03910d67c3 | |||
| fec5cc864e | |||
| cb78362713 | |||
| 4c5b1a6ff4 | |||
| 83c5727698 | |||
| 80838ff1e9 | |||
| 29e8d072b7 | |||
| d7592f01e1 | |||
| 392f283d9e | |||
| bcd738ebbb | |||
| 8020c52c48 | |||
| 3f566e541d | |||
| be4a631dc8 | |||
| 0bfdf908c1 | |||
| 6f2fc23f77 | |||
| f3a47c7e70 | |||
| 36349ffabb | |||
| b13f7366cf | |||
| 9181bcd9a7 | |||
| 7dbc1d894b | |||
| 5720445d15 | |||
| a90027521d | |||
| e02d400bf6 | |||
| efadb8fd31 | |||
| a19d06561b | |||
| 0b685d11c9 | |||
| 28f019d672 | |||
| bf5cbfffc2 | |||
| fe021e7c51 | |||
| c42fb54bc6 | |||
| 9382b68781 | |||
| 178198a417 | |||
| 7068e90771 | |||
| 1c762f23d0 | |||
| fd2b9a6e21 | |||
| db43910288 | |||
| f248c0460e | |||
| b8e3c0ceb4 | |||
| b5053d889e | |||
| 12ba7776b3 | |||
| 7817e88d03 | |||
| 8dec65853d | |||
| 88e3cb3be1 | |||
| fa702b48e3 | |||
| 299dcf6686 | |||
| 27f9ae5bbb | |||
| 9cb3a853f1 | |||
| 95c8ef4148 | |||
| a41bb52014 | |||
| 914cd7221e | |||
| 2dfc0a58ab | |||
| 0c9f3c638a | |||
| a966d6acf1 | |||
| 1e0c38b5f9 | |||
| d3323d6550 | |||
| ebed0b9f20 | |||
| f654a453dc | |||
| 10decf94cc | |||
| 96dd4817f1 | |||
| 72906cdc6a | |||
| fba4375be0 | |||
| 75120676ad | |||
| 7daf63fd3f | |||
| 014de25f6f | |||
| 3fc6535012 | |||
| 4fc0a32572 | |||
| dcc704a357 | |||
| bd8acbde97 | |||
| 112b10c19d | |||
| d89e561a85 | |||
| 49c1da79c8 | |||
| 0a72f00175 | |||
| 1af5820db0 | |||
| c117491549 | |||
| d8748f4270 | |||
| c0ba6e13e4 | |||
| c34daf1a35 | |||
| d461b53235 | |||
| c3ee14eb67 | |||
| 869fb8e327 | |||
| fbbc3024d6 | |||
| f1ba0c0aa7 | |||
| 54340ab4bf | |||
| 39732eee5e | |||
| a9e4526a6d | |||
| 57a6d2abf9 | |||
| d6246941ac | |||
| 2eb91f9b91 | |||
| 34ae413607 | |||
| ee9f8c184b | |||
| 7a84afcbdb | |||
| b8a16ea99d | |||
| 095466d5c7 | |||
| 89cfa22c3f | |||
| 1f18050930 | |||
| 537b78d564 | |||
| 717fd57ce1 | |||
| 3fb7786868 | |||
| 17ecfc9765 | |||
| 5326260a76 | |||
| e7522f4bdf | |||
| 504deeff42 | |||
| b7785b64cf | |||
| f914cb6858 | |||
| 91051d2521 | |||
| 51536a7acd | |||
| 263ccab6e3 | |||
| 9f87755dcb | |||
| 60b4cca5e5 | |||
| d2718e99a4 | |||
| 69a00c0ab3 | |||
| 3272d23917 | |||
| 7f0545cae7 | |||
| 68f35deb86 | |||
| c4f4035072 | |||
| a7d8845952 | |||
| a3378393b0 | |||
| 3dfe0ad478 | |||
| 9a3b7a4f3f | |||
| 78579b1103 | |||
| 7d50344512 | |||
| 7a00c12065 | |||
| af71e67681 | |||
| b3e20fc324 | |||
| bd1014abb6 | |||
| 7f76664a5d | |||
| 0a5a80b05d | |||
| 2d63da0660 | |||
| 8387527d2e | |||
| 5d03ba7d63 | |||
| 0ece50c122 | |||
| f2ac297252 | |||
| 0ca8ae17d4 | |||
| 88ca87cf9e | |||
| 0d69d228e4 | |||
| a3afe95306 | |||
| 9fb4af8658 | |||
| 9bb6ba9311 | |||
| faa42ba341 | |||
| 596827a912 | |||
| 89b4292445 | |||
| dd88737414 | |||
| 5456cfc304 | |||
| 1e66096ea7 | |||
| 2b6ae3908c | |||
| 1924612479 | |||
| 2af5bdeaab | |||
| b28565b38d | |||
| fec602362b | |||
| 6753c5f45a | |||
| 2f3c108d42 | |||
| ce6d99bdb4 | |||
| 86d4125893 | |||
| 3a18f00379 | |||
| e6274904a7 | |||
| 3677395444 | |||
| 22ba35b3b5 | |||
| 9c1ab9979b | |||
| eaa463e1c9 | |||
| 6984be48c3 | |||
| b739bd3d79 | |||
| 23f3e4396c | |||
| c264750924 | |||
| c155f0a5d5 | |||
| 76734f086d | |||
| 4f2d1172dd | |||
| 75caf4e297 | |||
| 509ab8261f | |||
| 1e05b40d4f | |||
| 451390f835 | |||
| 58cce9d2f8 | |||
| 2eb6e3b0ea | |||
| fb1181ed26 | |||
| 6d5e1d529d | |||
| 0e0ca08924 | |||
| 5d948a67a8 | |||
| 6a4db2ecab | |||
| f700273624 | |||
| 0c198e0ccc | |||
| 71ffbbc420 | |||
| 4fd09b889d | |||
| 4cb2a3eebe | |||
| c25186b1f6 | |||
| 779033d0bc | |||
| 3e31560e7d | |||
| d23d7e8775 | |||
| f6fdf5cb7f | |||
| 1879ccd27d | |||
| 08c0796719 | |||
| edc7994ce5 | |||
| bcfcfbd064 | |||
| 9e79b3258d | |||
| 243873cd2d | |||
| c7b8a4b0c1 | |||
| e39e0c7140 | |||
| d4a3f11dbb | |||
| 0962f266b3 | |||
| 69e4d3fdad | |||
| c0908f463a | |||
| b00a61a17b | |||
| 553c2f886a | |||
| 4fd9c5772a | |||
| 04e0e06d85 | |||
| 4d7829d72b | |||
| 6b751aac57 | |||
| 813349fd23 | |||
| 16a2744782 | |||
| 7b6870db22 | |||
| 3e38e7d52c | |||
| 8142d3474d | |||
| 8773649de6 | |||
| c117920ff9 | |||
| c8dd2a3eb8 | |||
| 90b1817e92 | |||
| d6c3ff5997 | |||
| 984ec25132 | |||
| a7bff34784 | |||
| a6e7afbc91 | |||
| 33f1d63b64 | |||
| f95e171e11 | |||
| c82b50b212 | |||
| 2b402b77f1 | |||
| adcb551020 | |||
| 2680aabe06 | |||
| d5c0533b74 | |||
| 609307668b | |||
| cdaf36572a | |||
| 033c8d5d51 | |||
| 6216ec1d6a | |||
| 6c9c67f6c5 | |||
| 5bd32b5521 | |||
| 549336f75b | |||
| f0e75f30b3 | |||
| 144c09f175 | |||
| ee50c0f97c | |||
| ade921bf02 | |||
| 676cacff04 | |||
| a3097d5e25 | |||
| fd78148558 | |||
| a4d79d7375 | |||
| df04e8183d | |||
| c43c484a62 | |||
| 0608c35669 | |||
| 7dd4d06e26 | |||
| 1ee0310b86 | |||
| cc0a52038f | |||
| 6aed1fe231 | |||
| 680608fe18 | |||
| ec6acbc602 | |||
| cb7ee4c5d2 | |||
| 88d5798f45 | |||
| fcc22a0aa3 | |||
| aabefff298 | |||
| ed25c64e97 | |||
| b7dc870c2d | |||
| 9bea608843 | |||
| 9db1732c36 | |||
| 39f1a70174 | |||
| 1810440355 | |||
| 37ac8f179e | |||
| 626a09328f | |||
| 8d489d0d77 | |||
| 776f3db0d7 | |||
| 6046057b88 | |||
| 7e85d9e549 | |||
| 01c8a8b1c2 | |||
| c9bf6ac9ae | |||
| 62e4d69be9 | |||
| 62ac733b09 | |||
| c3b3e1b1b9 | |||
| a791e96e00 | |||
| e87f5521c1 | |||
| 366a708f3a | |||
| 70ba662574 | |||
| b389abd99f | |||
| 4aa2d14fe3 | |||
| af7de75ad4 | |||
| d461ebbda1 | |||
| 55ef94abcd | |||
| afaf489d99 | |||
| 20e4cbfd13 | |||
| f3b8c9f34e | |||
| 45e8ff25a5 | |||
| 268e322e1c | |||
| d3bcba6a05 | |||
| cc4ef1944d | |||
| 5aa8486265 | |||
| fd181673cd | |||
| 62c9547c4e | |||
| cdd117bfb9 | |||
| 304ba57dad | |||
| 69eaaa4177 | |||
| 452ac52fcb | |||
| 40cf489290 | |||
| 891d6be4a6 | |||
| 5d45ce5cf7 | |||
| a0f2241f3a | |||
| aa513bf7d3 | |||
| b2d65febc8 | |||
| 23a6d326e8 | |||
| 5b2f1b6d8b | |||
| b4e9ad031b | |||
| 8b7ebcf040 | |||
| af05296631 | |||
| 29d693de2d | |||
| 51ac5172f5 | |||
| 24ce1ef5e7 | |||
| f6d1e269d1 | |||
| 62c2f5228d | |||
| 9882d9683b | |||
| 45ce89ee1f | |||
| bfb9df1553 | |||
| a5f79204ce | |||
| e322613d84 | |||
| fbb60f5191 | |||
| 899e7d2f39 | |||
| 8e2aa07747 | |||
| a0d262cd76 | |||
| b43a7edee4 | |||
| 7760bbd77c | |||
| 9c0f1b02a7 | |||
| 4ecfff4d8d | |||
| ac03b89f38 | |||
| 620174aea9 | |||
| ab50d28bc4 | |||
| b5318602d1 | |||
| bff2a63ea2 | |||
| aacfb8820e | |||
| 98e8c031d0 | |||
| beb4319d1e | |||
| 2558243c83 | |||
| b670e8d1ac | |||
| 68f8358f06 | |||
| db5a099097 | |||
| ce33ffb62a | |||
| 59a2fb9cfd | |||
| 75bba319de | |||
| f78e9261f3 | |||
| 5f77562333 | |||
| 5c4f01a68d | |||
| 35f6f998e6 | |||
| 6737a3ae09 | |||
| 09559bee8c | |||
| f487ea27a8 | |||
| a3d95f239a | |||
| 023c06e178 | |||
| 414a6c1c9e | |||
| 910e18fb22 | |||
| ac441fd1cf | |||
| 0c328372b5 | |||
| 55ef60a6d4 | |||
| c33584e683 | |||
| ee8c7453bd | |||
| 0330369603 | |||
| 3f7b642c7d | |||
| eb6c51426a | |||
| 0337bdb9fd | |||
| 7aedc62058 | |||
| bfc835cbbf | |||
| 5c6ba30c48 | |||
| 8fe4824ed2 | |||
| d40cb3bd55 | |||
| 4bcd3ac5d7 | |||
| e2b8e9dea9 | |||
| 572314bf3f | |||
| 14d303d331 | |||
| 24ffaa0738 | |||
| 5d9b6d056d | |||
| 5c28ff15ba | |||
| 06ceb2f2a1 | |||
| 7373e1dd8b | |||
| 4b1a9e714d | |||
| 9d76136358 | |||
| b3502420ad | |||
| dd7ac7cca9 | |||
| 31dfa18e9b | |||
| 3e785008d3 | |||
| 6b7c7f755c | |||
| c55a8a8703 | |||
| 64c97308ac | |||
| 3551b0b95a | |||
| 9f16b5c4af | |||
| 9777e549cb | |||
| fbfced1b93 | |||
| 1a84b4681c | |||
| 4bf81b8e1c | |||
| c282e7fdb4 | |||
| d339ee3135 | |||
| 1de95de299 | |||
| 96c998a1d7 | |||
| b5413c0156 | |||
| 7371c195ff | |||
| 0866a1996b | |||
| 41f44c4e78 | |||
| 131712c3bd | |||
| bae12aaab7 | |||
| 74d5844d8c | |||
| c87908266a | |||
| f788d76b8c | |||
| 41031e572e | |||
| f8a0864c1b | |||
| 949587334c | |||
| 0bc6a1a7f1 | |||
| 0d9cbfe927 | |||
| 8742a524c3 | |||
| 79bf2297b5 | |||
| 32e9e23630 | |||
| 7f1cecba92 | |||
| efd30c61c3 | |||
| 4c97b11207 | |||
| 58ea0ab745 | |||
| 3547c71ad5 | |||
| 044d6b2ce2 | |||
| a0b26b6c06 | |||
| 8e3bfde439 | |||
| 6507de959b | |||
| 56d09bf3b5 | |||
| 232754b978 | |||
| 75ef603308 | |||
| a5a2fcee4d | |||
| f86d57bfe3 | |||
| 615615b1df | |||
| aeba0ce170 | |||
| 5ce60aad53 | |||
| dbc01de9a0 | |||
| dfaf3f24fc | |||
| 14b0527e79 | |||
| f0148c3161 | |||
| 6a5e3d924d | |||
| 664a82e7c9 | |||
| e2763b4826 | |||
| afb29b19c2 | |||
| 8d60343940 | |||
| 67a77f1880 | |||
| c933974174 | |||
| 19715903fb | |||
| c88f72fd15 | |||
| 7818596271 | |||
| 9cb8d7bca6 | |||
| 46f9256114 | |||
| c26ef87202 | |||
| 89fee5b835 | |||
| f5795eb01b | |||
| dbf0c9f016 | |||
| 586b43048f |
@@ -1,7 +0,0 @@
|
||||
_darcs
|
||||
B
|
||||
ChangeLog.cvs*
|
||||
TODO.*
|
||||
build
|
||||
doxygen
|
||||
maint
|
||||
@@ -0,0 +1,48 @@
|
||||
syntax: regexp
|
||||
|
||||
^\.bzr
|
||||
^ChangeLog
|
||||
^build
|
||||
^maint
|
||||
|
||||
syntax: glob
|
||||
|
||||
*.a
|
||||
*.dll
|
||||
*.lib
|
||||
*.py[cdo]
|
||||
*.so
|
||||
*.swp
|
||||
|
||||
doc/*.1
|
||||
doc/*.doc
|
||||
doc/*.html
|
||||
doc/*.man
|
||||
doc/*.ps
|
||||
doc/*.tex
|
||||
|
||||
src/GNUmakefile
|
||||
src/MMakefile
|
||||
src/compress_nrv*
|
||||
src/*.mft
|
||||
src/*.rc
|
||||
|
||||
src/*.d
|
||||
src/*.exe
|
||||
src/*.map
|
||||
src/*.o
|
||||
src/*.obj
|
||||
src/*.out
|
||||
src/*.res
|
||||
src/*.ttp
|
||||
|
||||
stub/**MMakefile
|
||||
stub/**.*-stamp
|
||||
stub/tmp*/*
|
||||
stub/**/tmp*/*
|
||||
|
||||
stub/tools/armpe/armpe_tester
|
||||
|
||||
stub/tools/sstrip/amd64-linux-sstrip
|
||||
stub/tools/sstrip/i386-linux-sstrip
|
||||
stub/tools/sstrip/sstrip
|
||||
@@ -0,0 +1,11 @@
|
||||
140415ffbcef86a42b4d672249927364430d3d38 RELEASE_111
|
||||
223ac5b23f9731ceac9ff8d65167df4900776e36 RELEASE_190
|
||||
2c753c5bf38e7322715e2a5c6c5381111bd7a61a RELEASE_194
|
||||
2ee65b77f9117651e2e5517b2edede23698d73ca RELEASE_196
|
||||
70402aeee6e0e4fc2889658ed8cee44461c0b0a8 RELEASE_200
|
||||
a916a2fe22de45167d25abcb40008315f415221c RELEASE_201
|
||||
a935d577fc7dd9c2c87761c9c702805da6ce1e51 RELEASE_193
|
||||
b0353253b0b3d062eb5adb50d4b665a96620da45 RELEASE_195
|
||||
c2e0cd4d621b047f254f2def42132a03683ff52c RELEASE_192
|
||||
eb1ce56dce7dd1835964362470610925963b9043 RELEASE_110
|
||||
ed96891ef795bceec6b7ff3ca1ca7764431bfb39 RELEASE_191
|
||||
@@ -8,8 +8,8 @@
|
||||
|
||||
|
||||
The Ultimate Packer for eXecutables
|
||||
Copyright (c) 1996-2005 Markus Oberhumer & Laszlo Molnar
|
||||
http://upx.sourceforge.net
|
||||
Copyright (c) 1996-2006 Markus Oberhumer, Laszlo Molnar & John Reiser
|
||||
http://upx.sourceforge.net
|
||||
|
||||
|
||||
Limitations and other things which are not (yet) supported:
|
||||
|
||||
@@ -1,39 +1,47 @@
|
||||
# Toplevel Makefile for UPX
|
||||
#
|
||||
# UPX toplevel Makefile - needs GNU make 3.80 or better
|
||||
#
|
||||
|
||||
SHELL = /bin/sh
|
||||
MAKEFLAGS += -rR
|
||||
.SUFFIXES:
|
||||
export SHELL = /bin/sh
|
||||
|
||||
srcdir = .
|
||||
top_srcdir = .
|
||||
|
||||
|
||||
# info: src/stub needs GNU make 3.81 and special build tools
|
||||
BUILD_STUB = 0
|
||||
ifneq ($(wildcard $(HOME)/local/bin/bin-upx/.),)
|
||||
BUILD_STUB = 1
|
||||
endif
|
||||
ifneq ($(wildcard $(HOME)/bin/bin-upx/.),)
|
||||
BUILD_STUB = 1
|
||||
endif
|
||||
ifneq ($(findstring $(firstword $(MAKE_VERSION)),3.79 3.79.1 3.80),)
|
||||
BUILD_STUB = 0
|
||||
endif
|
||||
|
||||
|
||||
default:
|
||||
@echo "UPX info: please choose a target for 'make'"
|
||||
|
||||
all mostlyclean clean distclean maintainer-clean:
|
||||
$(MAKE) -C src/stub/util/sstrip $@
|
||||
ifeq ($(BUILD_STUB),1)
|
||||
$(MAKE) -C src/stub $@
|
||||
endif
|
||||
$(MAKE) -C src $@
|
||||
$(MAKE) -C doc $@
|
||||
|
||||
dist: distclean
|
||||
false
|
||||
|
||||
zip:
|
||||
cd .. && rm -f upx-current.zip && zip -r upx-current.zip upx
|
||||
|
||||
cvs-admin-ko:
|
||||
cvs admin -ko .
|
||||
cvs update -P -d
|
||||
|
||||
# automatically generate ChangeLog from Mercurial repo
|
||||
ChangeLog:
|
||||
perl $(srcdir)/scripts/cvs2cl.pl --utc -f ChangeLog.cvs
|
||||
|
||||
ChangeLog.cvsps:
|
||||
cvsps > $@
|
||||
ifneq ($(wildcard .hg/data/.),)
|
||||
hg log --style=changelog > $@
|
||||
else
|
||||
@echo "UPX info: no hg repo found"
|
||||
endif
|
||||
|
||||
|
||||
.PHONY: all mostlyclean clean distclean maintainer-clean
|
||||
.PHONY: dist cvs-admin-ko ChangeLog
|
||||
|
||||
.NOEXPORT:
|
||||
.PHONY: default all mostlyclean clean distclean maintainer-clean
|
||||
.PHONY: ChangeLog
|
||||
|
||||
|
||||
@@ -2,15 +2,66 @@
|
||||
User visible changes for UPX
|
||||
==================================================================
|
||||
|
||||
[ UNSTABLE BETA VERSION - please see README.1ST for some more info ]
|
||||
Changes in 2.90 (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
|
||||
* vmlinuz/386: fixed zlib uncompression problem on dos
|
||||
* major source code change: the runtime decompression stubs are now
|
||||
built from internal ELF objects
|
||||
|
||||
Changes in 2.02 (13 Aug 2006):
|
||||
* linux/386: work around Linux kernel bug (".bss" requires PF_W)
|
||||
* linux/ppc32, mach/ppc32: compressed programs now work on a 405 CPU
|
||||
* vmlinuz/386: fixed zlib uncompression problem on dos
|
||||
|
||||
Changes in 2.01 (06 Jun 2006):
|
||||
* arm/pe: better DLL support
|
||||
* dos/exe: device driver support added
|
||||
* linux/386: Fix --force-execve for PaX, grSecurity, and strict SELinux.
|
||||
/tmp must support execve(); therefore /tmp cannot be mounted 'noexec'.
|
||||
* win32/pe & arm/pe: added new option '--keep-resource=' for
|
||||
excluding selected resources from compression
|
||||
|
||||
Changes in 2.00 (27 Apr 2006):
|
||||
* linux/386: the stub now prints an error message if some strict
|
||||
SELinux mode does prevent runtime decompression and execution
|
||||
(for a fully SELinux-compatible but otherwise inferior compression
|
||||
format you can use the '--force-execve' option)
|
||||
* linux/386: worked around a problem where certain Linux kernels
|
||||
clobber the %ebx register during a syscall
|
||||
* win32/pe: disable filters for files with broken PE headers
|
||||
|
||||
Changes in 1.96 beta (13 Apr 2006):
|
||||
* arm/pe: added filter support
|
||||
* win32/pe: removed an unnecessary check so that Delphi 2006 and
|
||||
Digital Mars C++ programs finally are supported
|
||||
|
||||
Changes in 1.95 beta (09 Apr 2006):
|
||||
* arm/pe: added DLL support
|
||||
* arm/pe: added thumb mode stub support
|
||||
* arm/pe: added unpacking support
|
||||
* win32/pe: really worked around R6002 runtime errors
|
||||
|
||||
Changes in 1.94 beta (11 Mar 2006):
|
||||
* new format: added support for arm/pe (ARM executables running on WinCE)
|
||||
* new format: added support for linux elf/amd64
|
||||
* new format: added support for linux elf/ppc32
|
||||
* new format: added support for mach/ppc32 (Apple Mac OS X)
|
||||
* win32/pe: hopefully working "load config" support
|
||||
* win32/pe: R6002 runtime errors worked around
|
||||
* win32/pe: the stub now clears the dirty stack
|
||||
|
||||
Changes in 1.93 beta (07 Feb 2005):
|
||||
* UNSTABLE BETA VERSION - DO NOT USE EXCEPT FOR TESTING
|
||||
* vmlinuz/386: fixes to support more kernels
|
||||
|
||||
Changes in 1.92 beta (20 Jul 2004):
|
||||
* win32/pe: added option `--strip-loadconf' to strip the SEH
|
||||
load config section
|
||||
* win32/pe: added option '--strip-loadconf' to strip the SEH load
|
||||
config section [NOTE: this option is obsolete since UPX 1.94]
|
||||
* win32/pe: try to detect .NET (win32/net) files [not yet supported by UPX]
|
||||
* vmlinux/386: new format that directly supports building Linux kernels
|
||||
* source code: now compiles cleanly under Win64
|
||||
@@ -21,7 +72,7 @@ Changes in 1.91 beta (30 Jun 2004):
|
||||
* vmlinuz/386: added support for recent kernels
|
||||
* watcom/le: don't crash on files without relocations
|
||||
* win32/pe: stricter checks of some PE values
|
||||
* option `--brute' now implies `--crp-ms=999999'.
|
||||
* option '--brute' now implies '--crp-ms=999999'.
|
||||
* source code: much improved portability using ACC, the
|
||||
Automatic Compiler Configuration
|
||||
* source code: compile fixes for strict ISO C++ compilers
|
||||
@@ -30,9 +81,9 @@ Changes in 1.91 beta (30 Jun 2004):
|
||||
|
||||
Changes in 1.90 beta (11 Nov 2002):
|
||||
* implemented several new options for finer compression control:
|
||||
`--all-methods', `--all-filters' and `--brute'
|
||||
'--all-methods', '--all-filters' and '--brute'
|
||||
* ps1/exe: new format - UPX now supports PlayStation One programs
|
||||
* linux/386: added the option `--force-execve'
|
||||
* linux/386: added the option '--force-execve'
|
||||
* vmlinuz/386: better kernel detection and sanity checks
|
||||
* re-synced with upx 1.24 branch
|
||||
* documentation updates
|
||||
@@ -77,9 +128,9 @@ Changes in 1.22 (27 Jun 2002)
|
||||
Digital Mars C++ and Watcom C++
|
||||
|
||||
Changes in 1.21 (01 Jun 2002)
|
||||
* New option `--crp-ms=' for slightly better compression at the cost
|
||||
* New option '--crp-ms=' for slightly better compression at the cost
|
||||
of higher memory requirements during compression.
|
||||
Try `upx --best --crp-ms=100000'. See the docs for more info.
|
||||
Try 'upx --best --crp-ms=100000'. See the docs for more info.
|
||||
* source code: portability fixes
|
||||
* source code: compile fixes for g++ 3.0 and g++ 3.1
|
||||
|
||||
@@ -93,7 +144,6 @@ Changes in 1.20 (23 May 2001)
|
||||
our unstable development releases 1.1x and 1.9x]
|
||||
|
||||
Changes in 1.08 (30 Apr 2001)
|
||||
* INFO: http://upx.sourceforge.net now is the new permanent UPX home page
|
||||
* new native port to atari/tos
|
||||
* win32/pe: shortened the identstring
|
||||
* source code: portability fixes - UPX now builds cleanly under m68k CPUs
|
||||
@@ -118,7 +168,7 @@ Changes in 1.05 (24 Jan 2001)
|
||||
at the unstable UPX 1.1x beta versions for that)
|
||||
|
||||
Changes in 1.04 (19 Dec 2000)
|
||||
* dos/exe: fixed an internal error when using `--no-reloc'
|
||||
* dos/exe: fixed an internal error when using '--no-reloc'
|
||||
* win32/pe: fixed a rare bug in the relocation handling code
|
||||
* some tunings for the default compression level
|
||||
|
||||
@@ -126,7 +176,7 @@ Changes in 1.03 (30 Nov 2000)
|
||||
* linked with a new version of the NRV compression library:
|
||||
- improved compression ratio a little bit
|
||||
- overall significantly faster compression
|
||||
- much faster when using high compression levels like `-9' or `--best'
|
||||
- much faster when using high compression levels like '-9' or '--best'
|
||||
- much faster with large files
|
||||
* atari/tos: added support for FreeMiNT
|
||||
* the 32-bit DOS version now uses the new CWSDSTUB extender
|
||||
@@ -134,7 +184,7 @@ Changes in 1.03 (30 Nov 2000)
|
||||
Changes in 1.02 (13 Sep 2000)
|
||||
* watcom/le: fixed a problem with the Causeway extender
|
||||
* win32/pe: don't automatically strip relocs if they seem needed
|
||||
* support multiple backup generations when using `-k'
|
||||
* support multiple backup generations when using '-k'
|
||||
* updated the console screen driver
|
||||
|
||||
Changes in 1.01 (09 Apr 2000)
|
||||
@@ -162,7 +212,7 @@ Changes in 0.99.1 (29 Feb 2000)
|
||||
|
||||
Changes in 0.99 (25 Feb 2000)
|
||||
* FULL SOURCE CODE RELEASED UNDER THE TERMS OF THE GNU GPL
|
||||
* win32/pe: changed default to `--strip-relocs=1'
|
||||
* win32/pe: changed default to '--strip-relocs=1'
|
||||
* dos/com and dos/sys: fixed a bad decompressor problem
|
||||
* linux/386: the counter for the progress indicator was off by one
|
||||
|
||||
@@ -185,7 +235,7 @@ Changes in 0.91 (13 Nov 1999)
|
||||
* dos/exe: correctly restore cs when uncompressing
|
||||
|
||||
Changes in 0.90 (10 Nov 1999)
|
||||
* all formats: `--overlay=copy' now is the default overlay mode
|
||||
* all formats: '--overlay=copy' now is the default overlay mode
|
||||
* improved compression ratio for most files
|
||||
* win32/pe: uncompression is finally supported
|
||||
* win32/pe: never compress REGISTRY resources
|
||||
@@ -195,7 +245,7 @@ Changes in 0.90 (10 Nov 1999)
|
||||
* win32/pe: somewhat less memory is required during compression
|
||||
* linux/386: fixed compression of scripts which was broken since 0.71
|
||||
* linux/386: more FreeBSD compatibility issues
|
||||
* changed option: `-i' now prints some more details during compression
|
||||
* changed option: '-i' now prints some more details during compression
|
||||
(not finished yet)
|
||||
|
||||
Changes in 0.84 (04 Oct 1999)
|
||||
@@ -211,7 +261,7 @@ Changes in 0.83 (17 Sep 1999)
|
||||
Changes in 0.82 (16 Aug 1999)
|
||||
* dos/exe: fixed a decompressor bug which could cause crash on some files
|
||||
* linux/386: section headers are now stripped from the stub so that
|
||||
`strip' won't ruin a compressed file any longer
|
||||
'strip' won't ruin a compressed file any longer
|
||||
* wc/le: support for stack not in the last object disabled again
|
||||
* win32/pe: removed some unneeded data
|
||||
|
||||
@@ -220,32 +270,32 @@ Changes in 0.81 (04 Aug 1999)
|
||||
* dos/com: fixed an internal error that could happen with very small files
|
||||
|
||||
Changes in 0.80 (03 Aug 1999)
|
||||
* you can set some default options in the environment var `UPX'
|
||||
* you can set some default options in the environment var 'UPX'
|
||||
* dos/com: the decompressor stub now checks for enough free memory
|
||||
* dos/exe: decompressor rewritten, some bugs are fixed
|
||||
* dos/exe: new option `--no-reloc': no relocation data is put into
|
||||
* dos/exe: new option '--no-reloc': no relocation data is put into
|
||||
the DOS header
|
||||
* tmt/adam: added support for more stubs, detect already packed files
|
||||
* tmt/adam: new option `--copy-overlay'
|
||||
* tmt/adam: new option '--copy-overlay'
|
||||
* wc/le: reduced memory requirement during uncompression
|
||||
* wc/le: support files which do not contain their stack in the last object
|
||||
* wc/le: fixed a bug which could cause a crash, improved relocation
|
||||
handling
|
||||
* wc/le: new option `--copy-overlay'
|
||||
* win32/pe: `--compress-icons=2' is now the default
|
||||
* wc/le: new option '--copy-overlay'
|
||||
* win32/pe: '--compress-icons=2' is now the default
|
||||
* win32/pe: even better TLS support
|
||||
* win32/pe: versioninfo works on NT
|
||||
* win32/pe: import by ordinal from kernel32.dll works
|
||||
* win32/pe: other import improvements: importing a nonexistant DLL
|
||||
results in a usual Windows message, importing a nonexistant function
|
||||
results in program exit (instead of crash ;-)
|
||||
* win32/pe: new option: `--compress-resources=0'
|
||||
* win32/pe: new option: '--compress-resources=0'
|
||||
* win32/pe: reduced memory requirement during uncompression, some
|
||||
files might even require LESS memory when they're compressed
|
||||
* win32/pe: TYPELIBs should work now
|
||||
* win32/pe: improved relocation handling, 16-bit relocations should work
|
||||
* win32/pe: new option `--strip-relocs' (only if you know what you are doing)
|
||||
* win32/pe: new option `--copy-overlay'
|
||||
* win32/pe: new option '--strip-relocs' (only if you know what you are doing)
|
||||
* win32/pe: new option '--copy-overlay'
|
||||
* important internal changes: now the stubs are built at runtime
|
||||
|
||||
Changes in 0.72 (12 May 1999)
|
||||
@@ -259,20 +309,20 @@ Changes in 0.72 (12 May 1999)
|
||||
* linux/386: minor decompressor stub updates, nicer progress bar
|
||||
|
||||
Changes in 0.71 (19 Apr 1999)
|
||||
* dos/exe: added option `--no-overlay'
|
||||
* dos/exe: added option '--no-overlay'
|
||||
* linux/386: various improvements in the stub, most notably the
|
||||
overhead for an extra cleanup process has been removed
|
||||
* win32/pe: added support for export forwarders
|
||||
* win32/pe: added support for DLLs without entry point or imports
|
||||
* win32/pe: yet another .bss fix
|
||||
* win32/pe: new option `--compress-icons=2': compress all icons
|
||||
* win32/pe: new option '--compress-icons=2': compress all icons
|
||||
which are not in the first icon directory
|
||||
* win32/pe: rearranged stub to avoid false alerts from some virus scanners
|
||||
|
||||
Changes in 0.70 (30 Mar 1999)
|
||||
* added support for linux/386 executables
|
||||
* improved compression ratio quite a bit
|
||||
* added new compression level `--best' to squeeze out even some more bytes
|
||||
* added new compression level '--best' to squeeze out even some more bytes
|
||||
* win32/pe: TLS support is much better now
|
||||
* win32/pe: --compress-icons=0 should now work as well
|
||||
* the usual minor fixes for win32/pe
|
||||
@@ -313,7 +363,7 @@ Changes in 0.40 (05 Oct 1998)
|
||||
* fixed a small but fatal bug in dos/sys introduced in 0.30
|
||||
* fixed a rare bug in dos/exe
|
||||
* worked around a bug in djgpp's strip 2.8
|
||||
* Allegro packfile support should work now
|
||||
* djgpp/coff: Allegro packfile support should work now
|
||||
* added dos/exeh compression method (works on 386+)
|
||||
|
||||
Changes in 0.30 (27 Jul 1998)
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
|
||||
|
||||
The Ultimate Packer for eXecutables
|
||||
Copyright (c) 1996-2005 Markus Oberhumer & Laszlo Molnar
|
||||
http://upx.sourceforge.net
|
||||
Copyright (c) 1996-2006 Markus Oberhumer, Laszlo Molnar & John Reiser
|
||||
http://upx.sourceforge.net
|
||||
|
||||
|
||||
Here are some possible projects from which you can choose if you'd like to
|
||||
@@ -42,8 +42,6 @@ More formats:
|
||||
- freebsd/386 (generic), freebsd/elf386 (specialized).
|
||||
Probably could share most of the linux code.
|
||||
|
||||
- Windows CE
|
||||
|
||||
- add support for self-extracting HTML pages using a Javascript stub
|
||||
(like the AlgART HTML Packer "AHP")
|
||||
|
||||
@@ -58,8 +56,6 @@ Existing formats:
|
||||
|
||||
- dos/exe: implement filter support
|
||||
|
||||
- dos/sys: add support for sys/exe combos
|
||||
|
||||
- linux/i386:
|
||||
- use the new assembly preprocessor stuff (ie. process the file
|
||||
headers internally)
|
||||
@@ -70,8 +66,7 @@ Existing formats:
|
||||
|
||||
- win32/pe: display a nice dialog box in the stub in case
|
||||
of problems (like importing a DLL or function fails)
|
||||
- win32/pe: finer control over resource compression, per section
|
||||
compression
|
||||
- win32/pe: per section compression
|
||||
|
||||
|
||||
Compression ratio:
|
||||
|
||||
@@ -8,32 +8,11 @@
|
||||
|
||||
|
||||
The Ultimate Packer for eXecutables
|
||||
Copyright (c) 1996-2005 Markus Oberhumer & Laszlo Molnar
|
||||
http://upx.sourceforge.net
|
||||
Copyright (c) 1996-2006 Markus Oberhumer, Laszlo Molnar & John Reiser
|
||||
http://upx.sourceforge.net
|
||||
|
||||
|
||||
|
||||
WARNING - UNSTABLE BETA VERSION
|
||||
===============================
|
||||
|
||||
All versions 1.9x are unstable beta releases - use them only for testing,
|
||||
and never distribute a program that is packed with them !
|
||||
There will be hidden bugs. Really.
|
||||
|
||||
The current stable release is 1.25, and the next stable release
|
||||
will be called version 2.00.
|
||||
|
||||
The main news since 1.25 are:
|
||||
- slightly better compression using the new NRV2E algorithm
|
||||
- new options for compression tuining (e.g. `--brute')
|
||||
- support for bootable Linux kernels ("vmlinuz/386")
|
||||
- support for Linux kernel building ("vmlinux/386")
|
||||
- direct Linux ELF-to-memory decompression ("linux/elf386") and
|
||||
shell-to-memory decompression ("linux/sh386")
|
||||
- support for playstation exes ("ps1/exe")
|
||||
- lots of new bugs ;-) take care
|
||||
|
||||
|
||||
WELCOME
|
||||
=======
|
||||
|
||||
@@ -58,7 +37,7 @@ and run exactly as before, with no runtime or memory penalty for most
|
||||
of the supported formats.
|
||||
|
||||
UPX supports a number of different executable formats, including
|
||||
Windows 95/98/ME/NT/2000/XP programs and DLLs, DOS programs,
|
||||
Windows 95/98/ME/NT/2000/XP/CE programs and DLLs, DOS programs,
|
||||
and Linux executables and kernels.
|
||||
|
||||
UPX is free software distributed under the term of the GNU General
|
||||
@@ -76,8 +55,8 @@ UPX aims to be Commercial Quality Freeware.
|
||||
SHORT DOCUMENTATION
|
||||
===================
|
||||
|
||||
`upx program.exe' will compress a program or DLL. For best compression
|
||||
results try `upx --best program.exe'.
|
||||
'upx program.exe' will compress a program or DLL. For best compression
|
||||
results try 'upx --brute program.exe'.
|
||||
|
||||
Please see the file UPX.DOC for the full documentation. The files
|
||||
NEWS and BUGS also contain various tidbits of information.
|
||||
@@ -91,7 +70,7 @@ UPX comes with ABSOLUTELY NO WARRANTY; for details see the file LICENSE.
|
||||
Having said that, we think that UPX is quite stable now. Indeed we
|
||||
have compressed lots of files without any problems. Also, the
|
||||
current version has undergone several months of beta testing -
|
||||
actually it's more than 4 years since our first public beta.
|
||||
actually it's almost 8 years since our first public beta.
|
||||
|
||||
This is the first production quality release, and we plan that future
|
||||
releases will be backward compatible with this version.
|
||||
@@ -129,8 +108,9 @@ THE FUTURE
|
||||
COPYRIGHT
|
||||
=========
|
||||
|
||||
Copyright (C) 1996-2005 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2005 Laszlo Molnar
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
Copyright (C) 2000-2006 John F. Reiser
|
||||
|
||||
This program may be used freely, and you are welcome to
|
||||
redistribute it under certain conditions.
|
||||
@@ -149,7 +129,7 @@ Markus & Laszlo
|
||||
|
||||
|
||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
markus@oberhumer.com ml1050@cdata.tvnet.hu
|
||||
markus@oberhumer.com ml1050@users.sourceforge.net
|
||||
|
||||
|
||||
|
||||
|
||||
+12
-14
@@ -8,26 +8,24 @@
|
||||
|
||||
|
||||
The Ultimate Packer for eXecutables
|
||||
Copyright (c) 1996-2006 Markus Oberhumer, Laszlo Molnar & John Reiser
|
||||
http://upx.sourceforge.net
|
||||
|
||||
|
||||
|
||||
WARNING - UNSTABLE BETA VERSION
|
||||
===============================
|
||||
|
||||
All versions 1.9x are unstable beta releases - use them only for testing,
|
||||
and never distribute a program that is packed with them !
|
||||
There will be hidden bugs. Really.
|
||||
The current stable release is 2.02, and the next stable release
|
||||
will be called version 3.00.
|
||||
|
||||
The current stable release is 1.25, and the next stable release
|
||||
will be called version 2.00.
|
||||
|
||||
The main news since 1.25 are:
|
||||
- slightly better compression using the new NRV2E algorithm
|
||||
- new options for compression tuining (e.g. `--brute')
|
||||
- support for bootable Linux kernels ("vmlinuz/386")
|
||||
- support for Linux kernel building ("vmlinux/386")
|
||||
- direct Linux ELF-to-memory decompression ("linux/elf386") and
|
||||
shell-to-memory decompression ("linux/sh386")
|
||||
- support for playstation exes ("ps1/exe")
|
||||
- lots of new bugs ;-) take care
|
||||
MAJOR NEWS IN UPX 3
|
||||
===================
|
||||
|
||||
The main news since UPX 2 are:
|
||||
|
||||
* new format: added support for linux elf/arm
|
||||
|
||||
* better compression using the LZMA algorithm (option '--lzma')
|
||||
|
||||
|
||||
+14
-27
@@ -69,46 +69,34 @@ Tools needed to build/modify the UPX sources
|
||||
- A C++ compiler supporting inner classes, templates, exceptions
|
||||
and RTTI.
|
||||
|
||||
- GNU make 3.80 for Win32
|
||||
http://www.cygwin.com/
|
||||
|
||||
- GNU make 3.80 for DOS
|
||||
http://www.delorie.com/djgpp/
|
||||
- GNU make 3.80 or better (GNU make 3.81 recommened).
|
||||
|
||||
|
||||
To compile the packer sources
|
||||
-----------------------------
|
||||
|
||||
set the environment variable UCLDIR to point to your UCL installation, e.g.
|
||||
set the environment variable UPX_UCLDIR to point to your
|
||||
UCL installation, e.g.
|
||||
|
||||
set UCLDIR=c:\src\ucl-1.03 (DOS / Windows)
|
||||
export UCLDIR=$HOME/local/src/ucl-1.03 (Unix)
|
||||
set UPX_UCLDIR=c:\src\ucl-1.03 (DOS / Windows)
|
||||
export UPX_UCLDIR=$HOME/local/src/ucl-1.03 (Unix)
|
||||
|
||||
then type
|
||||
|
||||
make target=linux # linux
|
||||
make target=djgpp2 # dos32 - djgpp2
|
||||
make target=cygwin # win32 - cygwin 1.3.x
|
||||
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
|
||||
-------------------------------------------------------
|
||||
|
||||
- Nasm 0.98.38 - the Netwide Assembler
|
||||
http://upx.sourceforge.net/download/tools/
|
||||
http://sourceforge.net/projects/nasm/
|
||||
- GNU make 3.81 or better
|
||||
http://savannah.gnu.org/projects/make/
|
||||
|
||||
- A68K - a 68000 macro assembler
|
||||
http://upx.sourceforge.net/download/tools/
|
||||
- Perl & Python
|
||||
|
||||
- djasm - an assembler for the djgpp stub
|
||||
http://upx.sourceforge.net/download/tools/
|
||||
|
||||
- Perl 5.6 or better
|
||||
|
||||
- Linux (for the linux/386 stubs)
|
||||
- A number of cross-assemblers and cross-compilers - precompiled
|
||||
binaries for i386-linux hosts are available from
|
||||
http://sourceforge.net/project/showfiles.php?group_id=2331
|
||||
|
||||
|
||||
Misc. notes
|
||||
@@ -123,9 +111,6 @@ Misc. notes
|
||||
stream.
|
||||
- Use gcc extensions and other compiler specific stuff only through
|
||||
macros.
|
||||
- Keep in mind that it should be possible to build UPX on braindead
|
||||
file systems (FAT). Don't use long file names or other things
|
||||
that break building under plain DOS.
|
||||
|
||||
***
|
||||
|
||||
@@ -150,3 +135,5 @@ Patches/Contributions
|
||||
|
||||
diff -uNr olddirectory newdirectory
|
||||
|
||||
|
||||
# vi:ts=4:et
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
|
||||
|
||||
The Ultimate Packer for eXecutables
|
||||
Copyright (c) 1996-2005 Markus Oberhumer & Laszlo Molnar
|
||||
http://upx.sourceforge.net
|
||||
Copyright (c) 1996-2006 Markus Oberhumer, Laszlo Molnar & John Reiser
|
||||
http://upx.sourceforge.net
|
||||
|
||||
|
||||
.___.. .
|
||||
@@ -39,12 +39,12 @@ Ice
|
||||
for debugging the PE headersize problem down
|
||||
Joergen Ibsen <jibz@hotmail.com> and d'b
|
||||
for the relocation & address optimization ideas
|
||||
John F. Reiser <jreiser@BitWagon.com>
|
||||
for the new Linux executable formats
|
||||
John S. Fine <johnfine@erols.com>
|
||||
for the new version of the dos/exe decompressor
|
||||
Lukundoo <Lukundoo@softhome.net>
|
||||
for beta testing
|
||||
Michael Devore
|
||||
for initial dos/exe device driver support
|
||||
Oleg V. Volkov <rover@lglobus.ru>
|
||||
for various FreeBSD specific informations
|
||||
The Owl & G-RoM
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
UPX TODO list. Last updated 2005-01-08.
|
||||
UPX TODO list. Last updated 2006-03-11.
|
||||
|
||||
|
||||
IMPORTANT PROBLEMS THAT SHOULD BE FIXED SOON:
|
||||
|
||||
- stub ctojr32 needs CPU 486 because of bswap
|
||||
- [None]
|
||||
|
||||
|
||||
OTHER:
|
||||
|
||||
- rewrite linker.cpp to allow arbitrary length section names
|
||||
- docs: convert docs from upx.pod to use AsciiDoc
|
||||
|
||||
- check all <const_cast> to make sure they are not invalid
|
||||
|
||||
@@ -105,11 +105,6 @@ FORMAT WIN32/PE
|
||||
|
||||
- decrease runtime memory overhead
|
||||
|
||||
2 - easy - mfx + ml) new switch(es) : do not compress resource types x,y,z
|
||||
or resource names a,b,c
|
||||
|
||||
3 - medium - ml) rebuild exports
|
||||
|
||||
3 - difficult) don't compress the BSS section and other holes.
|
||||
|
||||
4 - medium - ml) fix when objectalign < 0x1000
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
upx.1
|
||||
upx.doc
|
||||
upx.html
|
||||
upx.man
|
||||
upx.ps
|
||||
upx.tex
|
||||
+51
-35
@@ -1,34 +1,51 @@
|
||||
#
|
||||
# UPX doc Makefile - needs GNU make 3.80 or better
|
||||
#
|
||||
|
||||
MAKEFLAGS += -rR
|
||||
.SUFFIXES:
|
||||
SHELL = /bin/sh
|
||||
|
||||
# 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
|
||||
VERSION_DATE = 07 Feb 2005
|
||||
VERSION := $(shell sed -n 's/^.*UPX_VERSION_STRING .*"\(.*\)".*/\1/p' $(top_srcdir)/src/version.h)
|
||||
PACKAGE = upx
|
||||
VERSION_DATE := $(shell sed -n 's/^.*UPX_VERSION_DATE_ISO .*"\(.*\)".*/\1/p' $(top_srcdir)/src/version.h)
|
||||
VERSION := $(shell sed -n 's/^.*UPX_VERSION_STRING .*"\(.*\)".*/\1/p' $(top_srcdir)/src/version.h)
|
||||
|
||||
TRIMSPACE = cat
|
||||
TRIMSPACE = sed -e 's/ *$$//'
|
||||
RTRIM := sed -e 's/[ $(tab)]*$$//'
|
||||
DETAB2 := sed -e 's/$(tab)/ /g'
|
||||
|
||||
BUILT_SOURCES = upx.1 upx.doc upx.html upx.man upx.ps upx.tex
|
||||
BUILT_SOURCES = upx.1 upx.doc upx.html
|
||||
|
||||
|
||||
###
|
||||
###
|
||||
### targets
|
||||
###
|
||||
|
||||
all: $(BUILT_SOURCES)
|
||||
|
||||
mostlyclean:
|
||||
-rm -f $(BUILT_SOURCES) pod2htm*
|
||||
|
||||
clean: mostlyclean
|
||||
|
||||
distclean: clean
|
||||
|
||||
maintainer-clean: distclean
|
||||
|
||||
.SUFFIXES: .1 .doc .html .man .pod .ps .tex .texi
|
||||
mostlyclean clean distclean maintainer-clean:
|
||||
rm -f $(BUILT_SOURCES) pod2htm*
|
||||
|
||||
.PHONY: all mostlyclean clean distclean maintainer-clean
|
||||
|
||||
@@ -37,32 +54,31 @@ maintainer-clean: distclean
|
||||
### rules
|
||||
###
|
||||
|
||||
.pod.1:
|
||||
pod2man --center=" " --release="$(PACKAGE) $(VERSION)" --date="$(VERSION_DATE)" $< | $(TRIMSPACE) > $@
|
||||
.SUFFIXES: .1 .doc .html .man .pod .ps .tex
|
||||
|
||||
.pod.html:
|
||||
### pod2html $< | $(TRIMSPACE) > $@
|
||||
pod2html --noindex $< | $(TRIMSPACE) > $@
|
||||
@-rm -f pod2htm*
|
||||
%.1 : %.pod
|
||||
pod2man --center=" " --release="$(PACKAGE) $(VERSION)" --date="$(VERSION_DATE)" $< | $(RTRIM) > $@
|
||||
|
||||
.pod.tex:
|
||||
%.doc : %.pod
|
||||
pod2text < $< | $(RTRIM) > $@
|
||||
|
||||
%.html : %.pod
|
||||
pod2html --noindex $< | $(RTRIM) | $(DETAB2) > $@
|
||||
@rm -f pod2htm*
|
||||
|
||||
%.man : %.1
|
||||
nroff -man $< | $(RTRIM) > $@
|
||||
|
||||
%.ps : %.1
|
||||
groff -man $< | $(RTRIM) > $@
|
||||
|
||||
%.tex : %.pod
|
||||
pod2latex $<
|
||||
|
||||
.pod.doc:
|
||||
pod2text < $< | $(TRIMSPACE) > $@
|
||||
|
||||
.1.man:
|
||||
nroff -man $< | $(TRIMSPACE) > $@
|
||||
|
||||
.1.ps:
|
||||
groff -man $< | $(TRIMSPACE) > $@
|
||||
|
||||
|
||||
###
|
||||
### dependencies
|
||||
###
|
||||
|
||||
$(BUILT_SOURCES): $(top_srcdir)/src/version.h Makefile
|
||||
|
||||
.NOEXPORT:
|
||||
$(BUILT_SOURCES): $(top_srcdir)/src/version.h $(MAKEFILE_LIST)
|
||||
|
||||
|
||||
+18
-2
@@ -1,5 +1,5 @@
|
||||
Decompressing ELF Directly to Memory on Linux/x86
|
||||
Copyright 2000 John F. Reiser jreiser@BitWagon.com
|
||||
Copyright (C) 2000-2006 John F. Reiser jreiser@BitWagon.com
|
||||
|
||||
References:
|
||||
<elf.h> definitions for the ELF file format
|
||||
@@ -17,7 +17,7 @@ program itself. So, the decompressor program (which contains the
|
||||
compressed version of the original executable) must have the same
|
||||
brk() as the original executable. So, the second PT_LOAD
|
||||
ELF "segment" of the compressed program is used only to set the brk(0).
|
||||
See src/p_lx_elf.cpp, function PackLinuxI386elf::patchLoader().
|
||||
See src/p_lx_elf.cpp, function PackLinuxElf32::generateElfHdr.
|
||||
All of the decompressor's code, and all of the compressed image
|
||||
of the original executable, reside in the first PT_LOAD of the
|
||||
decompressor program.
|
||||
@@ -63,3 +63,19 @@ clear the free portion of the stack (to compensate for ld-linux.so.2
|
||||
assuming that its automatic stack variables are initialized to zero),
|
||||
and remove (all but 4 bytes of) the decompression program (and
|
||||
compressed executable) from the address space.
|
||||
|
||||
Because the UPX runtime stub removes all traces of the compressed file
|
||||
from the address space, then the Linux kernel erases the symlink
|
||||
/proc/self/exe. Linux stores the pathname argument that was specified
|
||||
to execve() immediately after the '\0' which terminates the character
|
||||
string of the last environment variable [as of execve()]. This is true
|
||||
for at least all Linux 2.6, 2.4, and 2.2 kernels. The pathname is not
|
||||
"bound" to the file as strongly as /proc/self/exe (the file may be changed
|
||||
without affecting the pathname), but the pathname does provide some
|
||||
information. The pathname may be relative to the working directory,
|
||||
so look before any chdir().
|
||||
|
||||
The Elf formats for Linux add an environment variable named " " [three
|
||||
spaces] which saves the results of readlink("/proc/self/exe",,) before
|
||||
the runtime stub unmaps all its pages. As of 2006-10-03 this works
|
||||
for linux/elf386 and linux/ElfAMD.
|
||||
|
||||
+26
-65
@@ -2,16 +2,8 @@ This documentation is written for those brave souls who want to
|
||||
understand and/or modify the UPX assembly stubs - the small snippets
|
||||
that do the runtime decompression when a compressed program is started.
|
||||
|
||||
So, how the runtime stub/loader generation works?
|
||||
|
||||
You might have already noticed that for some file formats the loaders
|
||||
are quite simple (linux/i386 & tos) while in the other cases the
|
||||
loaders look very suspicious: they're full of `%ifdef's and contain
|
||||
loads of cryptic comments like `__PERELOC2__'.
|
||||
|
||||
If you look at the C++ source files, however you can notice that these
|
||||
comment strings (without the leading and trailing underscores) are used
|
||||
in the following way (they are all 8 character length strings):
|
||||
If you look at the C++ source files, you can find code fragments like
|
||||
this:
|
||||
|
||||
addLoader("PEMAIN20",
|
||||
ih.entry ? "PEDOJUMP" : "PERETURN",
|
||||
@@ -19,71 +11,40 @@ in the following way (they are all 8 character length strings):
|
||||
NULL
|
||||
);
|
||||
|
||||
Basically that's all you have to know: when you want to add a section
|
||||
of assembly code to the runtime loader, you just write
|
||||
linker->defineSymbol("original_entry", ih.entry);
|
||||
|
||||
l_foo.asm
|
||||
---------
|
||||
;__FOOBAR00__
|
||||
and in the assembly files fragments like this:
|
||||
|
||||
xor eax, eax
|
||||
label1:
|
||||
jmps label1
|
||||
section PEISDLL1
|
||||
cmpb [esp + 8], 1
|
||||
jnz reloc_end_jmp
|
||||
|
||||
;__FOOBARZZ__
|
||||
section PEMAIN21
|
||||
reloc_end_jmp:
|
||||
|
||||
p_foo.cpp
|
||||
---------
|
||||
section PERETURN
|
||||
xor eax, eax
|
||||
inc eax
|
||||
ret 0x0C
|
||||
section PEDOJUMP
|
||||
jmp original_entry
|
||||
|
||||
addLoader("FOOBAR00", NULL);
|
||||
|
||||
This will add the assembly section starting from __FOOBAR00__ and ending
|
||||
before __FOOBARZZ__ to the loader. You can add an %ifdef - %endif pair
|
||||
before these comments if you wish - but these conditionals will NOT be
|
||||
seen by the assembler, they are just syntactic sugar to make the code a
|
||||
little bit more readable and understandable. (Note however, that only
|
||||
%ifdefs which are started on the 1st column are removed by the upx
|
||||
assembly preprocessor program, so you can still use preprocessor
|
||||
conditionals if you wish - just write them starting from the 2nd
|
||||
column.)
|
||||
Everything works as you would expect. If you want to add the code
|
||||
fragment which is in `section PERETURN' to the runtime stub, then
|
||||
simply use `addLoader("PERETURN")' in the C++ source.
|
||||
|
||||
That's nice, you could say, but how cross section jumps and calls are
|
||||
handled? Well, that is the nicest part of this stuff - they are handled
|
||||
automatically. All you have to do is to add the required sections to the
|
||||
loader using `addLoader()' and the rest is done by upx. It will resolve
|
||||
every conditional or unconditional jumps or subrutine calls for you.
|
||||
every conditional or unconditional jumps or subroutine calls for you.
|
||||
|
||||
This functionality (we could say it's a simple linker) is achived by the
|
||||
assembly preprocessor (src/stub/scripts/app.pl) and a little C++ module
|
||||
(src/linker.cpp). And of course NASM - the Netwide Assembler. You can
|
||||
see what's going on behind the scenes - just do:
|
||||
You can also use (undefined) symbols in the assembly for values that
|
||||
can only be computed during compression time (like `original_entry').
|
||||
These symbols can be defined later in C++ using
|
||||
|
||||
cd src/stubs
|
||||
make maintainer-clean
|
||||
make all
|
||||
linker->defineSymbol("xx", yy)
|
||||
|
||||
This will rebuild all the loaders - and keep the temporary files (*.as[xy])
|
||||
which are seen by the assembler.
|
||||
|
||||
Currently this loader/stub building method only works with ix86
|
||||
assembly - both app.pl and linker.cpp heavily rely on this when dealing
|
||||
with cross section references.
|
||||
|
||||
And finally some important features/requirements you should be aware of:
|
||||
|
||||
- as previously stated - preprocessor conditionals starting on the 1st
|
||||
column are removed by app.pl
|
||||
- sections are separated by comments in the form `;__X1234567__'
|
||||
- jumps are recognized by searching for a word which starts with `j'
|
||||
and followed by a label - this also means that `jmp short label1'
|
||||
will NOT be recognized (but you can use a macro called `jmps' for it
|
||||
by adding `%define jmps jmp short' to the beginning of the file)
|
||||
- at the end of the file you need something like this
|
||||
|
||||
eof:
|
||||
; __XTHEENDX__
|
||||
section .data
|
||||
dd -1
|
||||
dw eof
|
||||
|
||||
That's all for now.
|
||||
This functionality (we could say it's a simple linker) is achived by
|
||||
compiling the assembly into an ELF object file which a little C++
|
||||
module (src/linker.cpp) can interpret and work with.
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
UPX and SELinux
|
||||
March 6, 2006
|
||||
|
||||
|
||||
When a program that has been compressed by UPX is run, the decompressor
|
||||
must create and write new memory pages of executable instructions.
|
||||
SELinux (Security Enhanced Linux) directly controls the conditions
|
||||
under which generating and/or executing new instructions is allowed,
|
||||
so the configuration settings of SELinux affect the running of programs
|
||||
that have been compressed by UPX.
|
||||
|
||||
In SELinux "strict enforcing" mode (the most restrictive), generating
|
||||
new instructions at runtime is not allowed at all: any page with
|
||||
PROT_EXEC permission must be mapped from a file in a mounted filesystem
|
||||
that has 'x' [eXecute] permission, and the generation of such files is
|
||||
also tightly controlled. A program that was compressed by UPX will not
|
||||
run in SELinux strict enforcing mode. Attempts will fail with exit
|
||||
code 127, and a record will be added to the history file
|
||||
/var/log/audit/audit.log.
|
||||
|
||||
In "targeted enforcing" mode, SELinux pays close attention mostly to
|
||||
designated processes that run with elevated privileges: web server,
|
||||
print server, login server, etc. Ordinary user excutables receive
|
||||
much less scrutiny. However, one of the eventual goals of SELinux is to
|
||||
eradicate runtime generation of instructions because of the possibility
|
||||
for exploitation by malware (virus, trojan, key logger, privilege
|
||||
elevation exploit, etc.) Thus targeted enforcing mode notices and
|
||||
logs the use of "execmem" capability that is used by a program which
|
||||
was compressed by UPX. In keeping with the goal of eventual prohibition,
|
||||
SELinux ordinarily would deny execmem. However, most current SELinux
|
||||
systems, including Fedora Core 5 [set for release March 15, 2006],
|
||||
override this with "allow_exemem=1" in /etc/selinux/targeted/booleans.
|
||||
Thus a program compressed by UPX will run in the default installed
|
||||
configuration (targeted enforcing, allow_execmem=1) of SELinux under
|
||||
Fedora Core 5. Each invocation will add a few lines to the log file
|
||||
/var/log/audit/audit.log, one line for each use of execmem. If the
|
||||
SELinux policy becomes more restrictive in the future, then a special
|
||||
SELinux class or other mechanism must be created for compressed programs,
|
||||
or else UPX-compressed executables will not run then.
|
||||
|
||||
In its "permissive" modes, SELinux just logs the potential problems,
|
||||
but otherwise does not interfere. A program compressed by UPX will run
|
||||
in any permissive mode.
|
||||
+54
-27
@@ -12,9 +12,9 @@ B<upx> S<[ I<command> ]> S<[ I<options> ]> I<filename>...
|
||||
|
||||
=head1 ABSTRACT
|
||||
|
||||
The Ultimate Packer for eXecutables
|
||||
Copyright (c) 1996-2005 Markus Oberhumer & Laszlo Molnar
|
||||
http://upx.sourceforge.net
|
||||
The Ultimate Packer for eXecutables
|
||||
Copyright (c) 1996-2006 Markus Oberhumer, Laszlo Molnar & John Reiser
|
||||
http://upx.sourceforge.net
|
||||
|
||||
|
||||
B<UPX> is a portable, extendable, high-performance executable packer for
|
||||
@@ -75,8 +75,13 @@ B<UPX> is a versatile executable packer with the following features:
|
||||
* rtm32/pe
|
||||
* tmt/adam
|
||||
* vmlinuz/386 [bootable Linux kernel]
|
||||
* vmlinux/386
|
||||
* watcom/le (supporting DOS4G, PMODE/W, DOS32a and CauseWay)
|
||||
* win32/pe
|
||||
* win32/pe (exe and dll)
|
||||
* arm/pe (exe and dll)
|
||||
* linux/elfamd64
|
||||
* linux/elfppc32
|
||||
* mach/elfppc32
|
||||
|
||||
- portable: UPX is written in portable endian-neutral C++
|
||||
|
||||
@@ -335,9 +340,6 @@ Extra options available for this executable format:
|
||||
|
||||
=head2 NOTES FOR DOS/SYS
|
||||
|
||||
You can only compress plain sys files, sys/exe (two in one)
|
||||
combos are not supported.
|
||||
|
||||
Compressed programs only work on a 286+.
|
||||
|
||||
Packed programs will be byte-identical to the original after uncompression.
|
||||
@@ -697,19 +699,20 @@ nostalgic feelings of one of the authors.
|
||||
Packed programs will be byte-identical to the original after uncompression,
|
||||
until further notice.
|
||||
|
||||
Maximum uncompressed size: ~1998848 bytes.
|
||||
Maximum uncompressed size: ~1.89 / ~7.60 Mbytes.
|
||||
|
||||
Notes:
|
||||
|
||||
- UPX creates as default a 'CD-Rom only' PS1/PS2 compatible executable.
|
||||
For transfer between client/target use options below.
|
||||
- UPX creates as default a suitable executable for CD-Mastering
|
||||
and console transfer. For a CD-Master main executable you could also try
|
||||
the special option "--boot-only" as descriped below.
|
||||
|
||||
- Normally the packed files use the same memory areas like the uncompressed
|
||||
versions, so they will not override other memory areas while unpacking.
|
||||
If this isn't possible UPX will abort showing a 'packed data overlap'
|
||||
error. With the "--force" option UPX will set a few 'bytes higher' loading
|
||||
offset for the packed file, but this isn't a real problem if it is a
|
||||
single or boot-only executable.
|
||||
error. With the "--force" option UPX will relocate the loading address
|
||||
for the packed file, but this isn't a real problem if it is a single or
|
||||
the main executable.
|
||||
|
||||
Extra options available for this executable format:
|
||||
|
||||
@@ -718,19 +721,23 @@ Extra options available for this executable format:
|
||||
the compression ratio in some cases, but usually
|
||||
the default method gives the best results anyway.
|
||||
|
||||
--boot-only The format will only run from a CD and may slightly
|
||||
improves the compression ratio. The decompression
|
||||
routines are faster than default ones.
|
||||
But it cannot be used for host/client transfer !
|
||||
--8-bit Uses 8 bit size compression [default: 32 bit]
|
||||
|
||||
--8mb-ram PSone has 8 MB ram available [default: 2 MB]
|
||||
|
||||
--boot-only This format is for main exes and CD-Mastering only !
|
||||
It may slightly improve the compression ratio,
|
||||
decompression routines are faster than default ones.
|
||||
But it cannot be used for console transfer !
|
||||
|
||||
--no-align This option disables CD mode 2 data sector format
|
||||
alignment. May slightly improves the compression ratio,
|
||||
but the compressed executable will not boot from a CD.
|
||||
Use it for client/target transfer only !
|
||||
Use it for console transfer only !
|
||||
|
||||
|
||||
|
||||
=head2 NOTES FOR RTM32/PE
|
||||
=head2 NOTES FOR RTM32/PE and ARM/PE
|
||||
|
||||
Same as win32/pe.
|
||||
|
||||
@@ -836,12 +843,19 @@ smaller, but it's still there.
|
||||
If you're running executables from network, then compressed programs
|
||||
will load faster, and require less bandwidth during execution.
|
||||
|
||||
DLLs are supported.
|
||||
DLLs are supported. But UPX compressed DLLs can not share common data and
|
||||
code when they got used by multiple applications. So compressing msvcrt.dll
|
||||
is a waste of memory, but compressing the dll plugins of a particular
|
||||
application may be a better idea.
|
||||
|
||||
Screensavers are supported, with the restriction that the filename
|
||||
must end with ".scr" (as screensavers are handled slightly different
|
||||
than normal exe files).
|
||||
|
||||
UPX compressed PE files has some minor memory overhead (usually in the
|
||||
10 - 30 kbytes range) which can be seen by specifying the "-i" command
|
||||
line switch during compression.
|
||||
|
||||
Extra options available for this executable format:
|
||||
|
||||
--compress-exports=0 Don't compress the export section.
|
||||
@@ -861,13 +875,26 @@ Extra options available for this executable format:
|
||||
|
||||
--compress-resources=0 Don't compress any resources at all.
|
||||
|
||||
--keep-resource=list Don't compress resources specified by the list.
|
||||
The members of the list are separated by commas.
|
||||
A list member has the following format: I<type[/name]>.
|
||||
I<Type> is the type of the resource. Standard types
|
||||
must be specified as decimal numbers, user types can be
|
||||
specified by decimal IDs or strings. I<Name> is the
|
||||
identifier of the resource. It can be a decimal number
|
||||
or a string. For example:
|
||||
|
||||
--keep-resource=2/MYBITMAP,5,6/12345
|
||||
|
||||
UPX won't compress the named bitmap resource "MYBITMAP",
|
||||
it leaves every dialog (5) resource uncompressed, and
|
||||
it won't touch the string table resource with identifier
|
||||
12345.
|
||||
|
||||
--force Force compression even when there is an
|
||||
unexpected value in a header field.
|
||||
Use with care.
|
||||
|
||||
--strip-loadconf=0 Don't strip Structured Exception Handling load config [DEFAULT].
|
||||
--strip-loadconf=1 Strip Structured Exception Handling load config.
|
||||
|
||||
--strip-relocs=0 Don't strip relocation records.
|
||||
--strip-relocs=1 Strip relocation records. [DEFAULT]
|
||||
This option only works on executables with base
|
||||
@@ -920,13 +947,13 @@ Please report all bugs immediately to the authors.
|
||||
|
||||
=head1 COPYRIGHT
|
||||
|
||||
Copyright (C) 1996-2005 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
|
||||
Copyright (C) 1996-2005 Laszlo Molnar
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
|
||||
Copyright (C) 2000-2005 John F. Reiser
|
||||
Copyright (C) 2000-2006 John F. Reiser
|
||||
|
||||
Copyright (C) 2002-2005 Jens Medoch
|
||||
Copyright (C) 2002-2006 Jens Medoch
|
||||
|
||||
This program may be used freely, and you are welcome to
|
||||
redistribute it under certain conditions.
|
||||
|
||||
@@ -1,101 +0,0 @@
|
||||
The GNU bfd binary file descriptor package, part of the GNU binutils package,
|
||||
contains code to recognize an Elf file by looking at fields in the file header.
|
||||
Many programs (such as gdb, size, objdump, objcopy, strip and others) use bfd.
|
||||
Unfortunately, bfd has been overly strict. In releases
|
||||
binutils-2.9.1.0.4, binutils-2.9.1.0.23, binutils-2.9.5.0.0,
|
||||
binutils-2.10.1,
|
||||
gdb-4.17, gdb-5.0,
|
||||
and probably others,
|
||||
bfd does not recognize a file with zero in Elf32_Ehdr.e_shoff, .e_shentsize,
|
||||
or .e_shnum, even though the operating system kernel does not care, and many
|
||||
bfd clients would work just fine in these cases.
|
||||
|
||||
Because of its desire to create small size compressed executables, UPX
|
||||
generates and uses Elf files with zero in .e_shoff, .e_shentsizes, and .e_shnum.
|
||||
As a result, many widely-distributed instances of gdb, size, objdump, etc.,
|
||||
refuse to work on UPX-packed executables.
|
||||
|
||||
Here is a patch to bfd/elfcode.h which enables many bfd clients to work
|
||||
with UPX-packed executables. The last two lines of the patch are
|
||||
if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) == -1)
|
||||
return -1;
|
||||
|
||||
|
||||
--- elfcode.h.orig Mon Jun 16 11:45:32 1997
|
||||
+++ elfcode.h Sat Apr 22 10:18:56 2000
|
||||
@@ -1,5 +1,5 @@
|
||||
/* ELF executable support for BFD.
|
||||
- Copyright 1991, 92, 93, 94, 95, 96, 1997 Free Software Foundation, Inc.
|
||||
+ Copyright 1991, 92, 93, 94, 95, 96, 97, 1998 Free Software Foundation, Inc.
|
||||
|
||||
Written by Fred Fish @ Cygnus Support, from information published
|
||||
in "UNIX System V Release 4, Programmers Guide: ANSI C and
|
||||
@@ -517,14 +517,14 @@
|
||||
elf_debug_file (i_ehdrp);
|
||||
#endif
|
||||
|
||||
- /* If there is no section header table, we're hosed. */
|
||||
- if (i_ehdrp->e_shoff == 0)
|
||||
+ /* If there is no section header table, and relocatable, then we're hosed. */
|
||||
+ if (i_ehdrp->e_shoff == 0 && i_ehdrp->e_type == ET_REL)
|
||||
goto got_wrong_format_error;
|
||||
|
||||
/* As a simple sanity check, verify that the what BFD thinks is the
|
||||
size of each section header table entry actually matches the size
|
||||
- recorded in the file. */
|
||||
- if (i_ehdrp->e_shentsize != sizeof (x_shdr))
|
||||
+ recorded in the file, but only if there are any sections. */
|
||||
+ if (i_ehdrp->e_shentsize != sizeof (x_shdr) && i_ehdrp->e_shnum != 0)
|
||||
goto got_wrong_format_error;
|
||||
|
||||
ebd = get_elf_backend_data (abfd);
|
||||
@@ -579,6 +579,7 @@
|
||||
/* Allocate space for a copy of the section header table in
|
||||
internal form, seek to the section header table in the file,
|
||||
read it in, and convert it to internal form. */
|
||||
+ if (i_ehdrp->e_shnum!=0) {
|
||||
i_shdrp = ((Elf_Internal_Shdr *)
|
||||
bfd_alloc (abfd, sizeof (*i_shdrp) * i_ehdrp->e_shnum));
|
||||
elf_elfsections (abfd) = ((Elf_Internal_Shdr **)
|
||||
@@ -609,6 +610,7 @@
|
||||
if (! bfd_section_from_shdr (abfd, i_ehdrp->e_shstrndx))
|
||||
goto got_no_match;
|
||||
}
|
||||
+ }
|
||||
|
||||
/* Read in the program headers. */
|
||||
if (i_ehdrp->e_phnum == 0)
|
||||
@@ -644,6 +646,7 @@
|
||||
bfd_section_from_shdr with it (since this particular strtab is
|
||||
used to find all of the ELF section names.) */
|
||||
|
||||
+ if (i_ehdrp->e_shstrndx != 0) {
|
||||
shstrtab = bfd_elf_get_str_section (abfd, i_ehdrp->e_shstrndx);
|
||||
if (!shstrtab)
|
||||
goto got_no_match;
|
||||
@@ -657,6 +660,7 @@
|
||||
if (! bfd_section_from_shdr (abfd, shindex))
|
||||
goto got_no_match;
|
||||
}
|
||||
+ }
|
||||
|
||||
/* Let the backend double check the format and override global
|
||||
information. */
|
||||
@@ -930,7 +934,7 @@
|
||||
{
|
||||
Elf_Internal_Shdr *hdr;
|
||||
Elf_Internal_Shdr *verhdr;
|
||||
- long symcount; /* Number of external ELF symbols */
|
||||
+ unsigned long symcount; /* Number of external ELF symbols */
|
||||
elf_symbol_type *sym; /* Pointer to current bfd symbol */
|
||||
elf_symbol_type *symbase; /* Buffer for generated bfd symbols */
|
||||
Elf_Internal_Sym i_sym;
|
||||
@@ -978,7 +982,7 @@
|
||||
sym = symbase = NULL;
|
||||
else
|
||||
{
|
||||
- long i;
|
||||
+ unsigned long i;
|
||||
|
||||
if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) == -1)
|
||||
return -1;
|
||||
-3220
File diff suppressed because it is too large
Load Diff
@@ -1,24 +0,0 @@
|
||||
GNUmakefile
|
||||
*.0??
|
||||
*.d
|
||||
*.dat
|
||||
*.idb
|
||||
*.img
|
||||
*.map
|
||||
*.raw
|
||||
*.rc
|
||||
*.rel
|
||||
*.res
|
||||
*.pdb
|
||||
*.upx
|
||||
.gdbinit
|
||||
.Attic
|
||||
.deps
|
||||
B
|
||||
compress_nrv.*
|
||||
upx
|
||||
upx_nrv
|
||||
upx_nrv.*
|
||||
upx_ucl
|
||||
upx_ucl.*
|
||||
version1*.h
|
||||
@@ -1,42 +0,0 @@
|
||||
ifeq ($(DEPS_DONE),)
|
||||
DEPS_DONE := 1
|
||||
|
||||
|
||||
# /***********************************************************************
|
||||
# // automated dependencies
|
||||
# ************************************************************************/
|
||||
|
||||
ifeq ($(DEPMODE),gcc)
|
||||
EXTRA_CFLAGS += -Wp,-MMD,.deps/$(*F).d
|
||||
EXTRA_CXXFLAGS += -Wp,-MMD,.deps/$(*F).d
|
||||
HAVE_DEPS := 1
|
||||
endif
|
||||
|
||||
ifeq ($(DEPMODE),linux-intelc)
|
||||
EXTRA_CFLAGS += -MMD -MF.deps/$(*F).d
|
||||
EXTRA_CXXFLAGS += -MMD -MF.deps/$(*F).d
|
||||
HAVE_DEPS := 1
|
||||
endif
|
||||
|
||||
ifeq ($(DEPMODE),linux-pgi)
|
||||
## NOTE: -MMD does not work...
|
||||
EXTRA_CFLAGS += -MD.deps/$(*F).d
|
||||
EXTRA_CXXFLAGS += -MD.deps/$(*F).d
|
||||
HAVE_DEPS := 1
|
||||
endif
|
||||
|
||||
|
||||
ifeq ($(HAVE_DEPS),1)
|
||||
ifeq ($(strip $(wildcard .deps)),)
|
||||
DEPS_MAGIC := $(shell mkdir .deps > /dev/null 2>&1 || :)
|
||||
else
|
||||
DEPS_FILES := $(wildcard .deps/*.d)
|
||||
ifneq ($(strip $(DEPS_FILES)),)
|
||||
include $(DEPS_FILES)
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
|
||||
endif # DEPS_DONE
|
||||
|
||||
@@ -1,71 +0,0 @@
|
||||
DEPMODE := gcc
|
||||
|
||||
|
||||
# /***********************************************************************
|
||||
# // defaults for gcc
|
||||
# ************************************************************************/
|
||||
|
||||
CC = gcc
|
||||
CXX = g++
|
||||
CFLAGS_OUTPUT = -o $@
|
||||
LINK_EXE_OUTPUT = -o $@
|
||||
|
||||
|
||||
CFLAGS_W =
|
||||
CFLAGS_M =
|
||||
CFLAGS_O =
|
||||
CXXFLAGS_W =
|
||||
CXXFLAGS_M =
|
||||
CXXFLAGS_O =
|
||||
|
||||
CFLAGS = $(call __mkflags,CFLAGS_W) $(call __mkflags,CFLAGS_M) $(call __mkflags,CFLAGS_O)
|
||||
CXXFLAGS = $(call __mkflags,CXXFLAGS_W) $(call __mkflags,CXXFLAGS_M) $(call __mkflags,CXXFLAGS_O)
|
||||
|
||||
|
||||
#
|
||||
# cflags
|
||||
#
|
||||
|
||||
##CFLAGS_WERROR = -Werror
|
||||
CFLAGS_WERROR =
|
||||
CFLAGS_W = $(CFLAGS_WERROR) -Wall -W -Wbad-function-cast -Wcast-align -Wcast-qual -Winline -Wmissing-declarations -Wmissing-prototypes -Wnested-externs -Wpointer-arith -Wshadow -Wwrite-strings
|
||||
CXXFLAGS_W = $(CFLAGS_WERROR) -Wall -W -Wcast-align -Wcast-qual -Winline -Woverloaded-virtual -Wpointer-arith -Wshadow -Wsign-promo -Wwrite-strings
|
||||
|
||||
##CFLAGS_M += -fno-builtin
|
||||
##CFLAGS_M += -malign-functions=0 -malign-jumps=0 -malign-loops=0
|
||||
CXXFLAGS_M = $(CFLAGS_M)
|
||||
|
||||
ifeq ($(DEBUG),1)
|
||||
CFLAGS_O = -g -O0
|
||||
else
|
||||
##CFLAGS_O = -Os -fstrict-aliasing
|
||||
CFLAGS_O = -O2 -fstrict-aliasing
|
||||
##CFLAGS_O = -O2 -fno-strict-aliasing
|
||||
endif
|
||||
CXXFLAGS_O = $(CFLAGS_O) -fconserve-space
|
||||
##CXXFLAGS += -fasynchronous-exceptions
|
||||
|
||||
|
||||
#
|
||||
# cxxflags for g++ 3.2 or better
|
||||
|
||||
##CXXFLAGS_W += -Wdisabled-optimization -Wpacked
|
||||
|
||||
|
||||
#
|
||||
# ldflags
|
||||
#
|
||||
|
||||
ifeq ($(DEBUG),1)
|
||||
LDFLAGS += -g
|
||||
else
|
||||
LDFLAGS += -s
|
||||
endif
|
||||
LDFLAGS += -Wl,-Map,$T.map
|
||||
|
||||
ifeq ($(WITH_ZLIB),1)
|
||||
LDLIBS += -lz
|
||||
endif
|
||||
|
||||
|
||||
# vi:nowrap
|
||||
@@ -1,48 +0,0 @@
|
||||
UDIR := $($(U)DIR)
|
||||
|
||||
ifneq ($(strip $(wildcard $(UDIR)/include)),) # { include
|
||||
DEFS += -DWITH_$(U)
|
||||
INCLUDES += -I$(UDIR)/include
|
||||
|
||||
ifeq ($(DEBUG),1)
|
||||
ifneq ($(strip $(wildcard $(UDIR)/build/debug/src/.libs)),)
|
||||
LIBDIRS += $(UDIR)/build/debug/src/.libs
|
||||
endif
|
||||
endif
|
||||
|
||||
ifneq ($(strip $(wildcard $(UDIR)/build/$(release)/src/.libs)),)
|
||||
LIBDIRS += $(UDIR)/build/$(release)/src/.libs
|
||||
else
|
||||
ifneq ($(strip $(wildcard $(UDIR)/build/$(target)/src/.libs)),)
|
||||
LIBDIRS += $(UDIR)/build/$(target)/src/.libs
|
||||
else
|
||||
ifneq ($(strip $(wildcard $(UDIR)/src/.libs)),)
|
||||
LIBDIRS += $(UDIR)/src/.libs
|
||||
else
|
||||
ifneq ($(strip $(wildcard $(UDIR)/build/release/src/.libs)),)
|
||||
LIBDIRS += $(UDIR)/build/release/src/.libs
|
||||
else
|
||||
ifneq ($(strip $(wildcard $(UDIR)/build/src/.libs)),)
|
||||
LIBDIRS += $(UDIR)/build/src/.libs
|
||||
else
|
||||
ifneq ($(strip $(wildcard $(UDIR))),)
|
||||
LIBDIRS += $(UDIR)
|
||||
DOS_LIBDIRS := $(DOS_LIBDIRS);$(UDIR)
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
LDLIBS += -l$(u)
|
||||
DOS_LDLIBS += $(u).lib
|
||||
|
||||
|
||||
DEFS := $(DEFS)
|
||||
INCLUDES := $(INCLUDES)
|
||||
LIBDIRS := $(LIBDIRS)
|
||||
LDLIBS := $(LDLIBS)
|
||||
DOS_LDLIBS := $(DOS_LDLIBS)
|
||||
|
||||
endif # } include
|
||||
+88
-72
@@ -1,88 +1,104 @@
|
||||
#
|
||||
# UPX Makefile (GNU make) - works with unix/win32/djgpp2
|
||||
#
|
||||
# usage:
|
||||
# `make target=linux' # linux
|
||||
# `make target=dos32-djggp2' # dos32 - djggp2
|
||||
# `make target=win32-cygwin' # win32 - cygwin
|
||||
# `make target=win32-mingw32' # win32 - mingw32
|
||||
# `make target=win32-rsxnt' # win32 - rsxnt
|
||||
# `make target=win32-bc' # win32 - Borland C++
|
||||
# `make target=win32-dm' # win32 - Digital Mars C++
|
||||
# `make target=win32-ic' # win32 - Intel C++
|
||||
# `make target=win32-vc' # win32 - Visual C++
|
||||
# `make target=win32-wc' # win32 - Watcom C++
|
||||
# `make target=cross-amd64-linux' # x86_64-linux cross compiler
|
||||
# `make target=cross-mingw32' # i586-mingw32msvc cross compiler
|
||||
# `make target=cross-mint' # m68k-atari-mint cross compiler
|
||||
# `make target=gcc' # generic gcc
|
||||
#
|
||||
# you can also set the `UPX_MAKE_TARGET' environment variable.
|
||||
# UPX Makefile - needs GNU make 3.80 or better
|
||||
#
|
||||
|
||||
MAKEFLAGS += -rR
|
||||
.SUFFIXES:
|
||||
export SHELL = /bin/sh
|
||||
override e = $($1) $(EXTRA_$1) $(upx_$1) $($(basename $(notdir $@)).$1)
|
||||
|
||||
# configuration section
|
||||
|
||||
ifeq ($(strip $(UCLDIR)),)
|
||||
# change this to reflect where the UCL library is
|
||||
UCLDIR = $(HOME)/local/src/ucl-1.03
|
||||
srcdir ?= $(dir $(word $(words $(MAKEFILE_LIST)),$(MAKEFILE_LIST)))
|
||||
ifneq ($(srcdir),./)
|
||||
srcdir := $(shell echo '$(srcdir)' | sed 's,/*$$,,')
|
||||
##$(info Info: using VPATH . $(srcdir))
|
||||
VPATH := . $(srcdir)
|
||||
endif
|
||||
|
||||
## you can set the default target here
|
||||
##target =
|
||||
ifeq ($(CXX),)
|
||||
CXX = g++
|
||||
endif
|
||||
ifeq ($(firstword $(CXX)),g++)
|
||||
USE_GNUC ?= 1
|
||||
endif
|
||||
ifeq ($(USE_GNUC),1)
|
||||
CXXFLAGS += -MMD
|
||||
ifeq ($(DEBUG),1)
|
||||
CXXFLAGS += -O0 -g
|
||||
else
|
||||
CXXFLAGS += -O2
|
||||
endif
|
||||
CXXFLAGS += -Wall -W -Wcast-align -Wcast-qual -Wpointer-arith -Wwrite-strings -Werror
|
||||
##CXXFLAGS += -Wshadow
|
||||
endif
|
||||
CPPFLAGS += $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES)
|
||||
CXXLD ?= $(CXX)
|
||||
|
||||
DEBUG = 0
|
||||
exeext ?= .out
|
||||
libext ?= .a
|
||||
objext ?= .o
|
||||
|
||||
srcdir = .
|
||||
top_srcdir = ..
|
||||
upx_SOURCES := $(wildcard $(srcdir)/*.cpp)
|
||||
upx_OBJECTS := $(notdir $(upx_SOURCES:.cpp=$(objext)))
|
||||
|
||||
# we need UCL and zlib - you can set envvar UPX_UCLDIR
|
||||
ifneq ($(wildcard $(UPX_UCLDIR)/include/ucl/ucl.h),)
|
||||
INCLUDES += -I$(UPX_UCLDIR)/include
|
||||
LIBS += $(addprefix -L,$(dir $(wildcard $(UPX_UCLDIR)/libucl$(libext) $(UPX_UCLDIR)/src/.libs/libucl$(libext))))
|
||||
endif
|
||||
LIBS += -lucl -lz
|
||||
# you should set envvar UPX_LZMADIR to point to your unpacked lzma443.tar.bz2
|
||||
ifneq ($(wildcard $(UPX_LZMADIR)/C/7zip/.),)
|
||||
DEFS += -DWITH_LZMA
|
||||
INCLUDES += -I$(UPX_LZMADIR)
|
||||
endif
|
||||
# you should set envvar UPX_LUADIR to point to your unpacked lua-5.1.1.tar.gz
|
||||
# [disabled for now]
|
||||
ifneq ($(wildcard $(UPX_LUADIR)/src/lua.h),)
|
||||
##DEFS += -DWITH_LUA
|
||||
##upx_SOURCES_LUA := $(wildcard $(UPX_LUADIR)/src/*.c)
|
||||
##upx_SOURCES_LUA := $(filter-out %lua.c, $(upx_SOURCES_LUA))
|
||||
##upx_SOURCES_LUA := $(filter-out %luac.c, $(upx_SOURCES_LUA))
|
||||
##upx_OBJECTS_LUA := $(notdir $(upx_SOURCES_LUA:.c=$(objext)))
|
||||
##upx_OBJECTS_LUA := $(addprefix lua_,$(upx_OBJECTS_LUA))
|
||||
##upx_OBJECTS += $(upx_OBJECTS_LUA)
|
||||
else
|
||||
##$(error please set UPX_LUADIR)
|
||||
endif
|
||||
|
||||
|
||||
##### You should not have to change anything below this line. #####
|
||||
all: upx$(exeext)
|
||||
|
||||
upx$(exeext): $(upx_OBJECTS) $(upx_DEPENDENCIES)
|
||||
$($(notdir $@).PRE_LINK_STEP)
|
||||
$(strip $(CXXLD) $(call e,CPPFLAGS) $(call e,CXXFLAGS) $(call e,LDFLAGS) -o $@ $(upx_OBJECTS) $(call e,LDADD) $(call e,LIBS))
|
||||
$($(notdir $@).POST_LINK_STEP)
|
||||
|
||||
%.o : %.cpp
|
||||
$(strip $(CXX) $(call e,CPPFLAGS) $(call e,CXXFLAGS) -o $@ -c $<)
|
||||
|
||||
|
||||
# /***********************************************************************
|
||||
# // object files
|
||||
# ************************************************************************/
|
||||
ifeq ($(USE_GNUC),1)
|
||||
##compress_lzma$(objext) : CXXFLAGS += -O3 -fomit-frame-pointer
|
||||
compress_lzma$(objext) : CXXFLAGS += -Wno-cast-qual
|
||||
compress_lzma$(objext) : CXXFLAGS += -Wno-non-virtual-dtor
|
||||
compress_lzma$(objext) : CXXFLAGS += -Wno-shadow
|
||||
compress_lzma$(objext) : CXXFLAGS += -Wno-unused
|
||||
##compress_lzma$(objext) : CXXFLAGS += -Wno-error
|
||||
endif
|
||||
|
||||
# these use exceptions & RTTI
|
||||
OBJECTS1 = \
|
||||
compress$o except$o file$o lefile$o \
|
||||
filter$o linker$o mem$o msg$o stdcxx$o work$o ui$o \
|
||||
packer$o packerf$o packhead$o packmast$o \
|
||||
p_com$o p_djgpp2$o p_elks$o p_exe$o \
|
||||
p_lx_elf$o p_lx_exc$o p_lx_sep$o p_lx_sh$o \
|
||||
p_ps1$o p_sys$o p_tmt$o p_tos$o \
|
||||
p_unix$o p_vmlinz$o p_vmlinx$o p_w16ne$o p_w32pe$o p_wcle$o
|
||||
|
||||
# no exceptions or RTTI
|
||||
OBJECTS2 = \
|
||||
filteri$o help$o main$o mygetopt$o snprintf$o util$o \
|
||||
c_init$o c_file$o c_none$o c_screen$o \
|
||||
s_object$o s_djgpp2$o s_vcsa$o s_win32$o
|
||||
|
||||
# pure C sources
|
||||
OBJECTS3 =
|
||||
|
||||
OBJECTS = $(OBJECTS1) $(OBJECTS2) $(OBJECTS3)
|
||||
LIBS =
|
||||
RESOURCES =
|
||||
ifneq ($(strip $(upx_OBJECTS_LUA)),)
|
||||
$(upx_OBJECTS_LUA) : lua_%.o : $(UPX_LUADIR)/src/%.c
|
||||
$(strip $(CXX) $(call e,CPPFLAGS) $(call e,CXXFLAGS) -o $@ -c $<)
|
||||
ifeq ($(USE_GNUC),1)
|
||||
$(upx_OBJECTS_LUA) : CXXFLAGS += -Wno-cast-align
|
||||
$(upx_OBJECTS_LUA) : CXXFLAGS += -Wno-cast-qual
|
||||
$(upx_OBJECTS_LUA) : CXXFLAGS += -Wno-error
|
||||
endif
|
||||
endif
|
||||
|
||||
|
||||
# /***********************************************************************
|
||||
# // main
|
||||
# ************************************************************************/
|
||||
mostlyclean clean distclean maintainer-clean:
|
||||
rm -f *.d *.map *.o *.obj *.res upx.exe upx.out upx.ttp upx$(exeext)
|
||||
|
||||
override WITH_ZLIB = 1
|
||||
|
||||
include $(srcdir)/Makefile.bld
|
||||
|
||||
|
||||
# /***********************************************************************
|
||||
# // dependencies
|
||||
# ************************************************************************/
|
||||
|
||||
include $(srcdir)/Makedefs.dep
|
||||
|
||||
$(OBJECTS): miniacc.h
|
||||
|
||||
# vi:nowrap
|
||||
-include *.d
|
||||
.PHONY: all mostlyclean clean distclean maintainer-clean
|
||||
|
||||
@@ -1,720 +0,0 @@
|
||||
# /***********************************************************************
|
||||
# // prepare setup
|
||||
# ************************************************************************/
|
||||
|
||||
SHELL = /bin/sh
|
||||
|
||||
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .a .c .cpp .exe .lib .o .obj .rc .res .ttp
|
||||
|
||||
|
||||
ifeq ($(srcdir),)
|
||||
srcdir = .
|
||||
endif
|
||||
|
||||
VPATH = $(srcdir)
|
||||
|
||||
|
||||
# auto-detect the target unless given on the commandline
|
||||
ifeq ($(strip $(target)),)
|
||||
# try environment variable UPX_MAKE_TARGET
|
||||
target := $(UPX_MAKE_TARGET)
|
||||
endif
|
||||
ifeq ($(strip $(target)),)
|
||||
ifneq ($(strip $(wildcard /usr/include/linux)),)
|
||||
target = linux
|
||||
endif
|
||||
##ifneq ($(strip $(wildcard /platform/sun4?/kernel/unix)),)
|
||||
##target = sparc-sun-solaris
|
||||
##endif
|
||||
endif
|
||||
|
||||
ifeq ($(strip $(target)),)
|
||||
include please_specify_a_target
|
||||
endif
|
||||
|
||||
|
||||
# util var for use in the rules - basename of the current target
|
||||
override T = $(basename $@)
|
||||
|
||||
# expand "VAR" into "$(VAR) $(EXTRA_VAR) $(UPX_EXTRA_VAR)"
|
||||
override __mkflags = $(strip $($(1)) $(EXTRA_$(1)) $(UPX_EXTRA_$(1)))
|
||||
|
||||
|
||||
# /***********************************************************************
|
||||
# // compiler defaults
|
||||
# ************************************************************************/
|
||||
|
||||
CC_SRC = $<
|
||||
CXX_SRC = $<
|
||||
CC_COMPILE = $(CC) $(CCARCH) $(call __mkflags,DEFS) $(call __mkflags,INCLUDES) $(call __mkflags,CFLAGS) $(CFLAGS_OUTPUT) -c $(CC_SRC)
|
||||
CXX_COMPILE = $(CXX) $(CXXARCH) $(call __mkflags,DEFS) $(call __mkflags,INCLUDES) $(call __mkflags,CXXFLAGS) $(CXXFLAGS_OUTPUT) -c $(CXX_SRC)
|
||||
CXX_LINK_EXE = $(CXXLD) $(CXXLDARCH) $(call __mkflags,LDFLAGS) $(LINK_EXE_OUTPUT) $^ $(call __mkflags,LDLIBS)
|
||||
STUBEDIT_EXE =
|
||||
STUBIFY_EXE =
|
||||
CHMOD_EXE =
|
||||
|
||||
o = .o
|
||||
a = .a
|
||||
e =
|
||||
DEFS =
|
||||
INCLUDES =
|
||||
LIBDIRS =
|
||||
DOS_LDLIBS =
|
||||
DOS_LIBDIRS =
|
||||
|
||||
# CC defaults
|
||||
CC = INVALID_TARGET_CC
|
||||
CCARCH =
|
||||
CFLAGS =
|
||||
CFLAGS_OUTPUT =
|
||||
|
||||
# CXX defaults
|
||||
CXX = $(CC)
|
||||
CXXARCH = $(CCARCH)
|
||||
CXXFLAGS = $(CFLAGS)
|
||||
CXXFLAGS_OUTPUT = $(CFLAGS_OUTPUT)
|
||||
|
||||
# CXXLD defaults
|
||||
CXXLD = $(CXX)
|
||||
CXXLDARCH = $(CXXARCH)
|
||||
LDFLAGS =
|
||||
LINK_EXE_OUTPUT =
|
||||
LDLIBS =
|
||||
LINK_EXE_LDFLAGS =
|
||||
|
||||
ifeq ($(DEBUG),1)
|
||||
DEFS += -DDEBUG
|
||||
## DEFS += -DTESTING
|
||||
endif
|
||||
|
||||
|
||||
# /***********************************************************************
|
||||
# // compression libraries
|
||||
# ************************************************************************/
|
||||
|
||||
ifeq ($(WITH_ZLIB),1)
|
||||
DOS_LDLIBS += zlib.lib
|
||||
ZLIBDIR:=$(strip $(subst \,/,$(ZLIBDIR)))
|
||||
ifneq ($(strip $(wildcard $(ZLIBDIR))),)
|
||||
ifneq ($(strip $(wildcard $(ZLIBDIR)/include/zlib.h)),)
|
||||
INCLUDES += -I$(ZLIBDIR)/include
|
||||
else
|
||||
ifneq ($(strip $(wildcard $(ZLIBDIR)/src/zlib.h)),)
|
||||
INCLUDES += -I$(ZLIBDIR)/src
|
||||
else
|
||||
ifneq ($(strip $(wildcard $(ZLIBDIR)/zlib.h)),)
|
||||
INCLUDES += -I$(ZLIBDIR)
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
UCLDIR:=$(strip $(subst \,/,$(UCLDIR)))
|
||||
NRVDIR:=$(strip $(subst \,/,$(NRVDIR)))
|
||||
u = ucl
|
||||
U = UCL
|
||||
upx_exe_tail =
|
||||
include $(srcdir)/Makedefs.inc
|
||||
ifneq ($(strip $(wildcard $(NRVDIR)/include/nrv)),)
|
||||
u = nrv
|
||||
U = NRV
|
||||
upx_exe_tail := _$(u)
|
||||
include $(srcdir)/Makedefs.inc
|
||||
endif
|
||||
upx_exe = upx$(upx_exe_tail)$(e)
|
||||
|
||||
override tmp := -Wl,--rpath,
|
||||
LDRPATH := $(addprefix $(tmp),$(LIBDIRS))
|
||||
LIBDIRS += .
|
||||
LDLIBDIRS := $(addprefix -L,$(LIBDIRS))
|
||||
|
||||
##LDFLAGS += $(LDRPATH)
|
||||
LDFLAGS += $(LDLIBDIRS)
|
||||
|
||||
|
||||
# /***********************************************************************
|
||||
# // compiler settings
|
||||
# ************************************************************************/
|
||||
|
||||
###
|
||||
### generic gcc
|
||||
###
|
||||
|
||||
ifeq ($(target),gcc)
|
||||
include $(srcdir)/Makedefs.gcc
|
||||
endif
|
||||
|
||||
|
||||
###
|
||||
### linux - gcc
|
||||
###
|
||||
|
||||
ifeq ($(target),linux)
|
||||
include $(srcdir)/Makedefs.gcc
|
||||
override arch := $(shell uname -m | sed -e 's/^i[3456789]86$$/i386/')
|
||||
ifeq ($(arch),i386)
|
||||
CCARCH += -march=i386 -mcpu=i686
|
||||
endif
|
||||
DEFS += -D_FILE_OFFSET_BITS=64
|
||||
LDLIBS += -lmcheck
|
||||
##CFLAGS_WERROR = -Werror
|
||||
ifeq ($(DEBUG),1)
|
||||
else
|
||||
##LDFLAGS += -static
|
||||
STUBEDIT_EXE = objcopy -S -R .comment -R .note $@
|
||||
ifeq ($(arch),i386)
|
||||
## STUBIFY_EXE = perl $(srcdir)/stub/scripts/brandelf.pl $@
|
||||
endif
|
||||
endif
|
||||
CHMOD_EXE = chmod 755 $@
|
||||
endif # linux
|
||||
|
||||
|
||||
###
|
||||
### linux/i386 - Borland C++ 5.7 (Kylix 3)
|
||||
###
|
||||
|
||||
ifeq ($(target),linux-bc57)
|
||||
##DEPMODE := linux-XXX ## FIXME
|
||||
CC = bc++ -q -3
|
||||
CFLAGS = -w '-w!'
|
||||
CFLAGS_OUTPUT = -o$@
|
||||
LDFLAGS += -ls
|
||||
LINK_EXE_OUTPUT = -e$@
|
||||
ifeq ($(WITH_ZLIB),1)
|
||||
LDLIBS += -lz
|
||||
endif
|
||||
# warning: do not use option `-d' --> incorrect string merging will happen
|
||||
ifeq ($(DEBUG),1)
|
||||
CFLAGS += -Od -dc
|
||||
else
|
||||
CFLAGS += -O2 -dc
|
||||
endif
|
||||
# transform `-lxx -lyy' into `libxx.a libyy.a'
|
||||
LDLIBS := $(shell echo "$(LDLIBS)" | perl -pe 's/-l(.+?)\b/lib\1.a/g')
|
||||
endif
|
||||
|
||||
|
||||
###
|
||||
### linux/i386 - Intel C++
|
||||
###
|
||||
|
||||
ifeq ($(target),linux-intelc)
|
||||
DEPMODE := linux-intelc
|
||||
CC = icc
|
||||
CXX = icpc
|
||||
CCARCH += -march=i386 -mcpu=i686 -nolib_inline
|
||||
DEFS += -D_FILE_OFFSET_BITS=64
|
||||
CFLAGS_OUTPUT = -o $@
|
||||
LINK_EXE_OUTPUT = -o $@
|
||||
ifeq ($(WITH_ZLIB),1)
|
||||
LDLIBS += -lz
|
||||
endif
|
||||
CFLAGS = $(CFLAGS_WERROR)
|
||||
ifeq ($(DEBUG),1)
|
||||
CFLAGS += -g -O0
|
||||
else
|
||||
CFLAGS += -O2
|
||||
endif
|
||||
LDFLAGS += -Wl,-Map,$T.map
|
||||
endif
|
||||
|
||||
|
||||
###
|
||||
### linux/i386 - Portland Group PGI C++ 5.x
|
||||
###
|
||||
|
||||
ifeq ($(target),linux-pgi)
|
||||
DEPMODE := linux-pgi
|
||||
CC = pgcc
|
||||
CXX = pgCC
|
||||
CCARCH += -tp=p6
|
||||
DEFS += -D_FILE_OFFSET_BITS=64
|
||||
CFLAGS_OUTPUT = -o $@
|
||||
LINK_EXE_OUTPUT = -o $@
|
||||
ifeq ($(WITH_ZLIB),1)
|
||||
LDLIBS += -lz
|
||||
endif
|
||||
##CFLAGS += -Minform=info
|
||||
CXXFLAGS = $(CFLAGS) -tused
|
||||
ifeq ($(DEBUG),1)
|
||||
else
|
||||
CFLAGS += -O2
|
||||
endif
|
||||
endif
|
||||
|
||||
|
||||
###
|
||||
### Linux cross compilers
|
||||
###
|
||||
|
||||
ifeq ($(target),cross-amd64-linux)
|
||||
include $(srcdir)/Makedefs.gcc
|
||||
CC = x86_64-linux-gcc
|
||||
CXX = x86_64-linux-g++
|
||||
LDLIBS += -lmcheck
|
||||
endif # cross-amd64-linux
|
||||
|
||||
ifeq ($(target),cross-m68k-linux)
|
||||
include $(srcdir)/Makedefs.gcc
|
||||
CC = m68k-linux-gcc
|
||||
CXX = m68k-linux-g++
|
||||
##LDLIBS += -lmcheck
|
||||
endif # cross-m68k-linux
|
||||
|
||||
|
||||
###
|
||||
### sparc-sun-solaris2.8
|
||||
###
|
||||
|
||||
ifeq ($(target),sparc-sun-solaris)
|
||||
include $(srcdir)/Makedefs.gcc
|
||||
endif
|
||||
|
||||
|
||||
###
|
||||
### Atari cross compilers
|
||||
###
|
||||
|
||||
ifeq ($(target),cross-mint)
|
||||
include $(srcdir)/Makedefs.gcc
|
||||
e = .ttp
|
||||
CC = m68k-atari-mint-gcc
|
||||
CXX = m68k-atari-mint-g++
|
||||
CCARCH += -m68000
|
||||
endif
|
||||
|
||||
ifeq ($(target),cross-mint-m68040)
|
||||
include $(srcdir)/Makedefs.gcc
|
||||
e = .ttp
|
||||
CC = m68k-atari-mint-gcc
|
||||
CXX = m68k-atari-mint-g++
|
||||
CCARCH += -m68040
|
||||
endif
|
||||
|
||||
ifeq ($(target),cross-mint-m68020-60)
|
||||
include $(srcdir)/Makedefs.gcc
|
||||
e = .ttp
|
||||
CC = m68k-atari-mint-gcc
|
||||
CXX = m68k-atari-mint-g++
|
||||
CCARCH += -m68020-60 -m68881
|
||||
endif
|
||||
|
||||
|
||||
###
|
||||
### dos32 - djgpp2 / emx
|
||||
###
|
||||
|
||||
ifeq ($(target),dos32-djgpp2)
|
||||
include $(srcdir)/Makedefs.gcc
|
||||
e = .exe
|
||||
CXX = gxx
|
||||
CCARCH += -march=i386 -mcpu=i686
|
||||
CFLAGS_WERROR = -Werror
|
||||
STUBEDIT_EXE = stubedit $@ bufsize=0xfc00
|
||||
ifneq ($(strip $(wildcard $(DJDIR)/bin/mfxdjstubify.ex[eE])),)
|
||||
ifneq ($(strip $(wildcard $(DJDIR)/bin/cwsdstub.ex[eE])),)
|
||||
STUBIFY_EXE = mfxdjstubify -v -s $(DJDIR)/bin/cwsdstub.exe $@
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(target),dos32-emx)
|
||||
include $(srcdir)/Makedefs.gcc
|
||||
e = .exe
|
||||
CXX = gcc
|
||||
CFLAGS_O = -O2
|
||||
CCARCH += -mno-probe
|
||||
LDFLAGS = -L. -s
|
||||
endif
|
||||
|
||||
|
||||
###
|
||||
### win32 - cygwin / mingw32 / rsxnt
|
||||
###
|
||||
|
||||
ifeq ($(target),win32-cygwin)
|
||||
include $(srcdir)/Makedefs.gcc
|
||||
##CXX = g++-2
|
||||
e = .exe
|
||||
CCARCH += -march=i386 -mcpu=i686
|
||||
LDLIBS += -lwinmm
|
||||
endif
|
||||
|
||||
ifeq ($(target),win32-mingw32)
|
||||
include $(srcdir)/Makedefs.gcc
|
||||
e = .exe
|
||||
CCARCH += -march=i386 -mcpu=i686
|
||||
LDLIBS += -lwinmm
|
||||
endif
|
||||
|
||||
# mingw32 cross compiler
|
||||
ifeq ($(target),cross-mingw32)
|
||||
include $(srcdir)/Makedefs.gcc
|
||||
e = .exe
|
||||
CC = i586-mingw32msvc-gcc
|
||||
CXX = i586-mingw32msvc-g++
|
||||
CCARCH += -march=i386 -mcpu=i686
|
||||
LDLIBS += -lwinmm
|
||||
endif
|
||||
|
||||
# rsxnt (g++ 2.8.1)
|
||||
ifeq ($(target),win32-rsxnt)
|
||||
include $(srcdir)/Makedefs.gcc
|
||||
e = .exe
|
||||
CXX = gcc
|
||||
CFLAGS_O = -O2
|
||||
CCARCH += -Zwin32 -Zsys -mno-probe
|
||||
LDFLAGS = -L. -s
|
||||
STUBEDIT_EXE = pestack -s1024 -c1024 $@
|
||||
endif
|
||||
|
||||
|
||||
###
|
||||
### win32 - Borland C++
|
||||
###
|
||||
|
||||
ifeq ($(target),win32-bc)
|
||||
o = .obj
|
||||
a = .lib
|
||||
e = .exe
|
||||
CC = bcc32 -3
|
||||
ifeq ($(UPX_BROKEN_INCLUDES),1)
|
||||
ifneq ($(srcdir),.)
|
||||
INCLUDES += -I$(srcdir)
|
||||
endif
|
||||
INCLUDES += -I$(srcdir)/acc
|
||||
ifneq ($(strip $(wildcard $(srcdir)/filter)),)
|
||||
INCLUDES += -I$(srcdir)/filter
|
||||
endif
|
||||
endif
|
||||
CFLAGS = -w -w-inl -g1
|
||||
CFLAGS_OUTPUT = -o$@
|
||||
LDFLAGS = -ls
|
||||
LINK_EXE_OUTPUT = -e$@
|
||||
LDLIBS = $(DOS_LDLIBS)
|
||||
ifeq ($(DEBUG),1)
|
||||
CFLAGS += -Od -d
|
||||
else
|
||||
CFLAGS += -O2 -d
|
||||
endif
|
||||
endif # win32-bc
|
||||
|
||||
|
||||
###
|
||||
### win32 - Digital Mars C++
|
||||
###
|
||||
|
||||
ifeq ($(target),win32-dm)
|
||||
o = .obj
|
||||
a = .lib
|
||||
e = .exe
|
||||
CC = dmc -mn
|
||||
CFLAGS = -w- -wx
|
||||
CXXFLAGS = $(CFLAGS) -Aa -Ab -Ae -Ar
|
||||
CFLAGS_OUTPUT = -o$@
|
||||
LDFLAGS = -L/map
|
||||
LINK_EXE_OUTPUT = -o$@
|
||||
LDLIBS = $(DOS_LDLIBS)
|
||||
ifeq ($(DEBUG),1)
|
||||
CFLAGS += -o- -g -s
|
||||
else
|
||||
CFLAGS += -o
|
||||
endif
|
||||
endif # win32-dm
|
||||
|
||||
|
||||
###
|
||||
### win32 - Intel C++
|
||||
###
|
||||
|
||||
ifeq ($(target),win32-ic)
|
||||
o = .obj
|
||||
a = .lib
|
||||
e = .exe
|
||||
CC = icl -nologo
|
||||
CFLAGS = -W3 -WX
|
||||
CXXFLAGS = $(CFLAGS) -EHac -GR
|
||||
LDFLAGS =
|
||||
LINK_EXE_OUTPUT = -Fe$@
|
||||
LINK_EXE_LDFLAGS = /link /map:$T.map
|
||||
##LINK_EXE_LDFLAGS += /verbose
|
||||
ifeq (1,2)
|
||||
# statically link libcmt.lib
|
||||
CC += -MT
|
||||
## DOS_LDLIBS := $(DOS_LDLIBS:.lib=_ml.lib)
|
||||
else
|
||||
# link against msvcrt.dll
|
||||
CC += -MD
|
||||
endif
|
||||
LDLIBS = $(DOS_LDLIBS)
|
||||
ifeq ($(DEBUG),1)
|
||||
CFLAGS += -Od -ZI
|
||||
LINK_EXE_LDFLAGS += /debug
|
||||
else
|
||||
CFLAGS += -O1 -GF
|
||||
LINK_EXE_LDFLAGS += /release
|
||||
endif
|
||||
RESOURCES := $(subst .rc,.res,$(notdir $(wildcard $(srcdir)/*.rc)))
|
||||
endif # win32-ic
|
||||
|
||||
|
||||
###
|
||||
### win32 - Metrowerks C++
|
||||
###
|
||||
|
||||
ifeq ($(target),win32-mwerks)
|
||||
o = .obj
|
||||
a = .lib
|
||||
e = .exe
|
||||
CC = mwcc -gccinc
|
||||
CFLAGS = -w on
|
||||
CXXFLAGS = $(CFLAGS)
|
||||
CFLAGS_OUTPUT = -o $@
|
||||
LDFLAGS = -lwinmm.lib -map $T.map
|
||||
LINK_EXE_OUTPUT = -o $@
|
||||
LDLIBS = $(DOS_LDLIBS)
|
||||
ifeq ($(DEBUG),1)
|
||||
CFLAGS += -opt full
|
||||
else
|
||||
CFLAGS +=
|
||||
endif
|
||||
endif # win32-mwerks
|
||||
|
||||
|
||||
###
|
||||
### win32 - Symantec C++
|
||||
###
|
||||
|
||||
ifeq ($(target),win32-sc)
|
||||
o = .obj
|
||||
a = .lib
|
||||
e = .exe
|
||||
CC = sc -mn
|
||||
CFLAGS = -w- -wx
|
||||
CXXFLAGS = $(CFLAGS) -EH -ER
|
||||
CFLAGS_OUTPUT = -o$@
|
||||
LDFLAGS = -L/map
|
||||
LINK_EXE_OUTPUT = -o$@
|
||||
LDLIBS = $(DOS_LDLIBS)
|
||||
ifeq ($(DEBUG),1)
|
||||
CFLAGS += -o- -g -s
|
||||
else
|
||||
CFLAGS += -o
|
||||
endif
|
||||
endif # win32-sc
|
||||
|
||||
|
||||
###
|
||||
### win32 - Visual C++
|
||||
###
|
||||
|
||||
ifeq ($(target),win32-vc)
|
||||
o = .obj
|
||||
a = .lib
|
||||
e = .exe
|
||||
CC = cl -nologo
|
||||
CFLAGS = -W4 -WX
|
||||
CXXFLAGS = $(CFLAGS) -EHac -GR
|
||||
LDFLAGS =
|
||||
LINK_EXE_OUTPUT = -Fe$@
|
||||
LINK_EXE_LDFLAGS = /link /map:$T.map
|
||||
##LINK_EXE_LDFLAGS += /verbose
|
||||
ifeq (1,1)
|
||||
# statically link libcmt.lib
|
||||
CC += -MT
|
||||
## DOS_LDLIBS := $(DOS_LDLIBS:.lib=_ml.lib)
|
||||
else
|
||||
# link against msvcrt.dll
|
||||
CC += -MD
|
||||
endif
|
||||
LDLIBS = $(DOS_LDLIBS)
|
||||
ifeq ($(DEBUG),1)
|
||||
CFLAGS += -Od -ZI
|
||||
LINK_EXE_LDFLAGS += /debug
|
||||
else
|
||||
CFLAGS += -O1 -GF
|
||||
LINK_EXE_LDFLAGS += /release
|
||||
##LINK_EXE_LDFLAGS += /opt:nowin98
|
||||
endif
|
||||
RESOURCES := $(subst .rc,.res,$(notdir $(wildcard $(srcdir)/*.rc)))
|
||||
endif # win32-vc
|
||||
|
||||
|
||||
###
|
||||
### win32 - Watcom C++
|
||||
###
|
||||
|
||||
ifeq ($(target),win32-wc)
|
||||
o = .obj
|
||||
a = .lib
|
||||
e = .exe
|
||||
CC = wcl386 -zq -bt=nt -mf -5r
|
||||
##CC = wcl386 -zq -bt=dos -l=CauseWay -mf -5r
|
||||
CFLAGS = -zc -w5 -we
|
||||
CXXFLAGS = $(CFLAGS) -xs -xr
|
||||
CFLAGS_OUTPUT = -fo=$@
|
||||
LDFLAGS = -k0x100000 -fm
|
||||
LINK_EXE_OUTPUT = -fe=$@
|
||||
LDLIBS = $(DOS_LDLIBS)
|
||||
CC_SRC = $(subst /,\\,$<)
|
||||
CXX_SRC = $(subst /,\\,$<)
|
||||
INCLUDES := $(strip $(subst /,\\,$(INCLUDES)))
|
||||
ifeq (1,2)
|
||||
WCL386 := $(INCLUDES)
|
||||
export WCL386
|
||||
INCLUDES :=
|
||||
endif
|
||||
ifeq ($(DEBUG),1)
|
||||
CFLAGS +=
|
||||
else
|
||||
# note: it seems that the optimizer is generating bad code with `-ox'
|
||||
CFLAGS += -olr
|
||||
endif
|
||||
endif # win32-wc
|
||||
|
||||
|
||||
###
|
||||
### win64 - Intel C++ [Itanium]
|
||||
###
|
||||
|
||||
ifeq ($(target),win64-ic)
|
||||
o = .obj
|
||||
a = .lib
|
||||
e = .exe
|
||||
CC = ecl -nologo
|
||||
CFLAGS = -W3
|
||||
CXXFLAGS = $(CFLAGS) -EHac -GR
|
||||
LDFLAGS =
|
||||
LINK_EXE_OUTPUT = -Fe$@
|
||||
LINK_EXE_LDFLAGS = /link /map:$T.map
|
||||
##LINK_EXE_LDFLAGS += /verbose
|
||||
ifeq (1,2)
|
||||
# statically link libcmt.lib
|
||||
CC += -MT
|
||||
## DOS_LDLIBS := $(DOS_LDLIBS:.lib=_ml.lib)
|
||||
else
|
||||
# link against msvcrt.dll
|
||||
CC += -MD
|
||||
endif
|
||||
LDLIBS = $(DOS_LDLIBS)
|
||||
ifeq ($(DEBUG),1)
|
||||
CFLAGS += -Od -ZI
|
||||
LINK_EXE_LDFLAGS += /debug
|
||||
else
|
||||
CFLAGS += -O1 -GF
|
||||
LINK_EXE_LDFLAGS += /release
|
||||
endif
|
||||
RESOURCES := $(subst .rc,.res,$(notdir $(wildcard $(srcdir)/*.rc)))
|
||||
endif # win64-ic
|
||||
|
||||
|
||||
###
|
||||
### win64 - Visual C++ [AMD64 or Itanium]
|
||||
###
|
||||
|
||||
ifeq ($(target),win64-vc)
|
||||
o = .obj
|
||||
a = .lib
|
||||
e = .exe
|
||||
CC = cl -nologo
|
||||
CFLAGS = -W4 -Wall
|
||||
CXXFLAGS = $(CFLAGS) -EHac -GR
|
||||
LDFLAGS =
|
||||
LINK_EXE_OUTPUT = -Fe$@
|
||||
LINK_EXE_LDFLAGS = /link /map:$T.map
|
||||
##LINK_EXE_LDFLAGS += /verbose
|
||||
ifeq (1,1)
|
||||
# statically link libcmt.lib
|
||||
CC += -MT
|
||||
## DOS_LDLIBS := $(DOS_LDLIBS:.lib=_ml.lib)
|
||||
else
|
||||
# link against msvcrt.dll
|
||||
CC += -MD
|
||||
endif
|
||||
LDLIBS = $(DOS_LDLIBS)
|
||||
ifeq ($(DEBUG),1)
|
||||
CFLAGS += -Od -ZI
|
||||
LINK_EXE_LDFLAGS += /debug
|
||||
else
|
||||
CFLAGS += -O1 -GF
|
||||
LINK_EXE_LDFLAGS += /release
|
||||
endif
|
||||
RESOURCES := $(subst .rc,.res,$(notdir $(wildcard $(srcdir)/*.rc)))
|
||||
endif # win64-vc
|
||||
|
||||
|
||||
# /***********************************************************************
|
||||
# // malloc debuggers and memory checkers - obsolete, use valgrind
|
||||
# ************************************************************************/
|
||||
|
||||
ifeq (1,2)
|
||||
# compile in extra valgrind support
|
||||
DEFS += -DWITH_VALGRIND
|
||||
endif
|
||||
|
||||
ifeq (1,2)
|
||||
LDLIBS += -lefence
|
||||
endif
|
||||
|
||||
ifeq (1,2)
|
||||
DEFS += -DWITH_DMALLOC
|
||||
LDLIBS += -ldmalloc
|
||||
endif
|
||||
|
||||
ifeq (1,2)
|
||||
DEFS += -DWITH_GC -DLINUX_THREADS -D_REENTRANT
|
||||
LDLIBS += -lgc -lpthread
|
||||
# only needed when using -static:
|
||||
##LDFLAGS += -Wl,-defsym,_DYNAMIC=0
|
||||
endif
|
||||
|
||||
|
||||
# /***********************************************************************
|
||||
# // main targets
|
||||
# ************************************************************************/
|
||||
|
||||
-include ./Makefile.local
|
||||
|
||||
all: $(upx_exe)
|
||||
|
||||
$(upx_exe): $(OBJECTS) $(LIBS) $(RESOURCES)
|
||||
$(strip $(CXX_LINK_EXE))
|
||||
$(strip $(STUBEDIT_EXE))
|
||||
$(strip $(STUBIFY_EXE))
|
||||
$(strip $(CHMOD_EXE))
|
||||
|
||||
mostlyclean:
|
||||
-rm -f *.d *.err *.i *.log *.map gdb-trans*
|
||||
|
||||
clean: mostlyclean
|
||||
-rm -f *.a *.lib *.o *.obj *.res *.tds tags TAGS ID
|
||||
-rm -f *.idb *.pdb
|
||||
-rm -f $(upx_exe) upx upx.exe upx.ttp upx_nrv upx_nrv.exe upx_nrv.ttp upx_ucl upx_ucl.exe upx_ucl.ttp
|
||||
-rm -rf .deps _deps
|
||||
|
||||
distclean: clean
|
||||
|
||||
maintainer-clean: distclean
|
||||
|
||||
.PHONY: all mostlyclean clean distclean maintainer-clean
|
||||
|
||||
|
||||
# /***********************************************************************
|
||||
# // rules
|
||||
# ************************************************************************/
|
||||
|
||||
%$o : %.c
|
||||
$(strip $(CC_COMPILE))
|
||||
|
||||
%$o : %.cpp
|
||||
$(strip $(CXX_COMPILE))
|
||||
|
||||
%.res : %.rc
|
||||
rc -l 0x409 -fo$@ $<
|
||||
|
||||
|
||||
# vi:nowrap
|
||||
+311
-173
@@ -2,8 +2,8 @@
|
||||
|
||||
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) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -34,132 +34,147 @@
|
||||
// core
|
||||
**************************************************************************/
|
||||
|
||||
inline unsigned get_be16(const void *bb)
|
||||
inline unsigned get_be16(const void *p)
|
||||
{
|
||||
const unsigned char* b = (const unsigned char*) bb;
|
||||
unsigned v;
|
||||
v = (unsigned) b[1] << 0;
|
||||
v |= (unsigned) b[0] << 8;
|
||||
return v;
|
||||
}
|
||||
|
||||
inline void set_be16(void *bb, unsigned v)
|
||||
{
|
||||
unsigned char* b = (unsigned char*) bb;
|
||||
b[1] = (unsigned char) (v >> 0);
|
||||
b[0] = (unsigned char) (v >> 8);
|
||||
}
|
||||
|
||||
|
||||
inline unsigned get_be24(const void *bb)
|
||||
{
|
||||
const unsigned char* b = (const unsigned char*) bb;
|
||||
unsigned v;
|
||||
v = (unsigned) b[2] << 0;
|
||||
v |= (unsigned) b[1] << 8;
|
||||
v |= (unsigned) b[0] << 16;
|
||||
return v;
|
||||
}
|
||||
|
||||
inline void set_be24(void *bb, unsigned v)
|
||||
{
|
||||
unsigned char* b = (unsigned char*) bb;
|
||||
b[2] = (unsigned char) (v >> 0);
|
||||
b[1] = (unsigned char) (v >> 8);
|
||||
b[0] = (unsigned char) (v >> 16);
|
||||
}
|
||||
|
||||
|
||||
inline unsigned get_be32(const void *bb)
|
||||
{
|
||||
const unsigned char* b = (const unsigned char*) bb;
|
||||
unsigned v;
|
||||
v = (unsigned) b[3] << 0;
|
||||
v |= (unsigned) b[2] << 8;
|
||||
v |= (unsigned) b[1] << 16;
|
||||
v |= (unsigned) b[0] << 24;
|
||||
return v;
|
||||
}
|
||||
|
||||
inline void set_be32(void *bb, unsigned v)
|
||||
{
|
||||
unsigned char* b = (unsigned char*) bb;
|
||||
b[3] = (unsigned char) (v >> 0);
|
||||
b[2] = (unsigned char) (v >> 8);
|
||||
b[1] = (unsigned char) (v >> 16);
|
||||
b[0] = (unsigned char) (v >> 24);
|
||||
}
|
||||
|
||||
|
||||
inline unsigned get_le16(const void *bb)
|
||||
{
|
||||
#if defined(ACC_GET_LE16)
|
||||
return ACC_GET_LE16(bb);
|
||||
#if defined(ACC_UA_GET_BE16)
|
||||
return ACC_UA_GET_BE16(p);
|
||||
#else
|
||||
const unsigned char* b = (const unsigned char*) bb;
|
||||
unsigned v;
|
||||
v = (unsigned) b[0] << 0;
|
||||
v |= (unsigned) b[1] << 8;
|
||||
return v;
|
||||
return acc_ua_get_be16(p);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void set_le16(void *bb, unsigned v)
|
||||
inline void set_be16(void *p, unsigned v)
|
||||
{
|
||||
#if defined(ACC_SET_LE16)
|
||||
ACC_SET_LE16(bb, v);
|
||||
#if defined(ACC_UA_SET_BE16)
|
||||
ACC_UA_SET_BE16(p, v);
|
||||
#else
|
||||
unsigned char* b = (unsigned char*) bb;
|
||||
b[0] = (unsigned char) (v >> 0);
|
||||
b[1] = (unsigned char) (v >> 8);
|
||||
acc_ua_set_be16(p, v);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
inline unsigned get_le24(const void *bb)
|
||||
inline unsigned get_be24(const void *p)
|
||||
{
|
||||
const unsigned char* b = (const unsigned char*) bb;
|
||||
unsigned v;
|
||||
v = (unsigned) b[0] << 0;
|
||||
v |= (unsigned) b[1] << 8;
|
||||
v |= (unsigned) b[2] << 16;
|
||||
return v;
|
||||
}
|
||||
|
||||
inline void set_le24(void *bb, unsigned v)
|
||||
{
|
||||
unsigned char* b = (unsigned char*) bb;
|
||||
b[0] = (unsigned char) (v >> 0);
|
||||
b[1] = (unsigned char) (v >> 8);
|
||||
b[2] = (unsigned char) (v >> 16);
|
||||
}
|
||||
|
||||
|
||||
inline unsigned get_le32(const void *bb)
|
||||
{
|
||||
#if defined(ACC_GET_LE32)
|
||||
return ACC_GET_LE32(bb);
|
||||
#if defined(ACC_UA_GET_BE24)
|
||||
return ACC_UA_GET_BE24(p);
|
||||
#else
|
||||
const unsigned char* b = (const unsigned char*) bb;
|
||||
unsigned v;
|
||||
v = (unsigned) b[0] << 0;
|
||||
v |= (unsigned) b[1] << 8;
|
||||
v |= (unsigned) b[2] << 16;
|
||||
v |= (unsigned) b[3] << 24;
|
||||
return v;
|
||||
return acc_ua_get_be24(p);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void set_le32(void *bb, unsigned v)
|
||||
inline void set_be24(void *p, unsigned v)
|
||||
{
|
||||
#if defined(ACC_SET_LE32)
|
||||
ACC_SET_LE32(bb, v);
|
||||
#if defined(ACC_UA_SET_BE24)
|
||||
ACC_UA_SET_BE24(p, v);
|
||||
#else
|
||||
unsigned char* b = (unsigned char*) bb;
|
||||
b[0] = (unsigned char) (v >> 0);
|
||||
b[1] = (unsigned char) (v >> 8);
|
||||
b[2] = (unsigned char) (v >> 16);
|
||||
b[3] = (unsigned char) (v >> 24);
|
||||
acc_ua_set_be24(p, v);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline unsigned get_be32(const void *p)
|
||||
{
|
||||
#if defined(ACC_UA_GET_BE32)
|
||||
return ACC_UA_GET_BE32(p);
|
||||
#else
|
||||
return acc_ua_get_be32(p);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void set_be32(void *p, unsigned v)
|
||||
{
|
||||
#if defined(ACC_UA_SET_BE32)
|
||||
ACC_UA_SET_BE32(p, v);
|
||||
#else
|
||||
acc_ua_set_be32(p, v);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline acc_uint64l_t get_be64(const void *p)
|
||||
{
|
||||
#if defined(ACC_UA_GET_BE64)
|
||||
return ACC_UA_GET_BE64(p);
|
||||
#else
|
||||
return acc_ua_get_be64(p);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void set_be64(void *p, acc_uint64l_t v)
|
||||
{
|
||||
#if defined(ACC_UA_SET_BE64)
|
||||
ACC_UA_SET_BE64(p, v);
|
||||
#else
|
||||
acc_ua_set_be64(p, v);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline unsigned get_le16(const void *p)
|
||||
{
|
||||
#if defined(ACC_UA_GET_LE16)
|
||||
return ACC_UA_GET_LE16(p);
|
||||
#else
|
||||
return acc_ua_get_le16(p);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void set_le16(void *p, unsigned v)
|
||||
{
|
||||
#if defined(ACC_UA_SET_LE16)
|
||||
ACC_UA_SET_LE16(p, v);
|
||||
#else
|
||||
acc_ua_set_le16(p, v);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline unsigned get_le24(const void *p)
|
||||
{
|
||||
#if defined(ACC_UA_GET_LE24)
|
||||
return ACC_UA_GET_LE24(p);
|
||||
#else
|
||||
return acc_ua_get_le24(p);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void set_le24(void *p, unsigned v)
|
||||
{
|
||||
#if defined(ACC_UA_SET_LE24)
|
||||
ACC_UA_SET_LE24(p, v);
|
||||
#else
|
||||
acc_ua_set_le24(p, v);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline unsigned get_le32(const void *p)
|
||||
{
|
||||
#if defined(ACC_UA_GET_LE32)
|
||||
return ACC_UA_GET_LE32(p);
|
||||
#else
|
||||
return acc_ua_get_le32(p);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void set_le32(void *p, unsigned v)
|
||||
{
|
||||
#if defined(ACC_UA_SET_LE32)
|
||||
ACC_UA_SET_LE32(p, v);
|
||||
#else
|
||||
acc_ua_set_le32(p, v);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline acc_uint64l_t get_le64(const void *p)
|
||||
{
|
||||
#if defined(ACC_UA_GET_LE64)
|
||||
return ACC_UA_GET_LE64(p);
|
||||
#else
|
||||
return acc_ua_get_le64(p);
|
||||
#endif
|
||||
}
|
||||
|
||||
inline void set_le64(void *p, acc_uint64l_t v)
|
||||
{
|
||||
#if defined(ACC_UA_SET_LE64)
|
||||
ACC_UA_SET_LE64(p, v);
|
||||
#else
|
||||
acc_ua_set_le64(p, v);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -170,47 +185,66 @@ inline void set_le32(void *bb, unsigned v)
|
||||
|
||||
inline int sign_extend(int v, int bits)
|
||||
{
|
||||
const int sign_bit = 1 << (bits - 1);
|
||||
v |= -(v & sign_bit);
|
||||
const unsigned sign_bit = 1u << (bits - 1);
|
||||
v |= 0u - (v & sign_bit);
|
||||
return v;
|
||||
}
|
||||
|
||||
inline int get_be16_signed(const void *bb)
|
||||
inline acc_int64l_t sign_extend(acc_int64l_t v, int bits)
|
||||
{
|
||||
int v = get_be16(bb);
|
||||
const acc_uint64l_t sign_bit = ACC_UINT64_C(1) << (bits - 1);
|
||||
v |= ACC_UINT64_C(0) - (v & sign_bit);
|
||||
return v;
|
||||
}
|
||||
|
||||
inline int get_be16_signed(const void *p)
|
||||
{
|
||||
int v = get_be16(p);
|
||||
return sign_extend(v, 16);
|
||||
}
|
||||
|
||||
inline int get_be24_signed(const void *bb)
|
||||
inline int get_be24_signed(const void *p)
|
||||
{
|
||||
int v = get_be24(bb);
|
||||
int v = get_be24(p);
|
||||
return sign_extend(v, 24);
|
||||
}
|
||||
|
||||
inline int get_be32_signed(const void *bb)
|
||||
inline int get_be32_signed(const void *p)
|
||||
{
|
||||
int v = get_be32(bb);
|
||||
int v = get_be32(p);
|
||||
return sign_extend(v, 32);
|
||||
}
|
||||
|
||||
inline int get_le16_signed(const void *bb)
|
||||
inline acc_int64l_t get_be64_signed(const void *p)
|
||||
{
|
||||
int v = get_le16(bb);
|
||||
acc_int64l_t v = get_be64(p);
|
||||
return sign_extend(v, 64);
|
||||
}
|
||||
|
||||
inline int get_le16_signed(const void *p)
|
||||
{
|
||||
int v = get_le16(p);
|
||||
return sign_extend(v, 16);
|
||||
}
|
||||
|
||||
inline int get_le24_signed(const void *bb)
|
||||
inline int get_le24_signed(const void *p)
|
||||
{
|
||||
int v = get_le24(bb);
|
||||
int v = get_le24(p);
|
||||
return sign_extend(v, 24);
|
||||
}
|
||||
|
||||
inline int get_le32_signed(const void *bb)
|
||||
inline int get_le32_signed(const void *p)
|
||||
{
|
||||
int v = get_le32(bb);
|
||||
int v = get_le32(p);
|
||||
return sign_extend(v, 32);
|
||||
}
|
||||
|
||||
inline acc_int64l_t get_le64_signed(const void *p)
|
||||
{
|
||||
acc_int64l_t v = get_le64(p);
|
||||
return sign_extend(v, 64);
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// classes for portable unaligned access
|
||||
@@ -227,8 +261,13 @@ struct BE16
|
||||
BE16& operator = (unsigned v) { set_be16(d, v); return *this; }
|
||||
BE16& operator += (unsigned v) { set_be16(d, get_be16(d) + v); return *this; }
|
||||
BE16& operator -= (unsigned v) { set_be16(d, get_be16(d) - v); return *this; }
|
||||
BE16& operator *= (unsigned v) { set_be16(d, get_be16(d) * v); return *this; }
|
||||
BE16& operator /= (unsigned v) { set_be16(d, get_be16(d) / v); return *this; }
|
||||
BE16& operator &= (unsigned v) { set_be16(d, get_be16(d) & v); return *this; }
|
||||
BE16& operator |= (unsigned v) { set_be16(d, get_be16(d) | v); return *this; }
|
||||
BE16& operator ^= (unsigned v) { set_be16(d, get_be16(d) ^ v); return *this; }
|
||||
BE16& operator <<= (unsigned v) { set_be16(d, get_be16(d) << v); return *this; }
|
||||
BE16& operator >>= (unsigned v) { set_be16(d, get_be16(d) >> v); return *this; }
|
||||
|
||||
operator unsigned () const { return get_be16(d); }
|
||||
}
|
||||
@@ -242,14 +281,39 @@ struct BE32
|
||||
BE32& operator = (unsigned v) { set_be32(d, v); return *this; }
|
||||
BE32& operator += (unsigned v) { set_be32(d, get_be32(d) + v); return *this; }
|
||||
BE32& operator -= (unsigned v) { set_be32(d, get_be32(d) - v); return *this; }
|
||||
BE32& operator *= (unsigned v) { set_be32(d, get_be32(d) * v); return *this; }
|
||||
BE32& operator /= (unsigned v) { set_be32(d, get_be32(d) / v); return *this; }
|
||||
BE32& operator &= (unsigned v) { set_be32(d, get_be32(d) & v); return *this; }
|
||||
BE32& operator |= (unsigned v) { set_be32(d, get_be32(d) | v); return *this; }
|
||||
BE32& operator ^= (unsigned v) { set_be32(d, get_be32(d) ^ v); return *this; }
|
||||
BE32& operator <<= (unsigned v) { set_be32(d, get_be32(d) << v); return *this; }
|
||||
BE32& operator >>= (unsigned v) { set_be32(d, get_be32(d) >> v); return *this; }
|
||||
|
||||
operator unsigned () const { return get_be32(d); }
|
||||
}
|
||||
__attribute_packed;
|
||||
|
||||
|
||||
struct BE64
|
||||
{
|
||||
unsigned char d[8];
|
||||
|
||||
BE64& operator = (acc_uint64l_t v) { set_be64(d, v); return *this; }
|
||||
BE64& operator += (acc_uint64l_t v) { set_be64(d, get_be64(d) + v); return *this; }
|
||||
BE64& operator -= (acc_uint64l_t v) { set_be64(d, get_be64(d) - v); return *this; }
|
||||
BE64& operator *= (acc_uint64l_t v) { set_be64(d, get_be64(d) * v); return *this; }
|
||||
BE64& operator /= (acc_uint64l_t v) { set_be64(d, get_be64(d) / v); return *this; }
|
||||
BE64& operator &= (acc_uint64l_t v) { set_be64(d, get_be64(d) & v); return *this; }
|
||||
BE64& operator |= (acc_uint64l_t v) { set_be64(d, get_be64(d) | v); return *this; }
|
||||
BE64& operator ^= (acc_uint64l_t v) { set_be64(d, get_be64(d) ^ v); return *this; }
|
||||
BE64& operator <<= (unsigned v) { set_be64(d, get_be64(d) << v); return *this; }
|
||||
BE64& operator >>= (unsigned v) { set_be64(d, get_be64(d) >> v); return *this; }
|
||||
|
||||
operator acc_uint64l_t () const { return get_be64(d); }
|
||||
}
|
||||
__attribute_packed;
|
||||
|
||||
|
||||
struct LE16
|
||||
{
|
||||
unsigned char d[2];
|
||||
@@ -257,8 +321,13 @@ struct LE16
|
||||
LE16& operator = (unsigned v) { set_le16(d, v); return *this; }
|
||||
LE16& operator += (unsigned v) { set_le16(d, get_le16(d) + v); return *this; }
|
||||
LE16& operator -= (unsigned v) { set_le16(d, get_le16(d) - v); return *this; }
|
||||
LE16& operator *= (unsigned v) { set_le16(d, get_le16(d) * v); return *this; }
|
||||
LE16& operator /= (unsigned v) { set_le16(d, get_le16(d) / v); return *this; }
|
||||
LE16& operator &= (unsigned v) { set_le16(d, get_le16(d) & v); return *this; }
|
||||
LE16& operator |= (unsigned v) { set_le16(d, get_le16(d) | v); return *this; }
|
||||
LE16& operator ^= (unsigned v) { set_le16(d, get_le16(d) ^ v); return *this; }
|
||||
LE16& operator <<= (unsigned v) { set_le16(d, get_le16(d) << v); return *this; }
|
||||
LE16& operator >>= (unsigned v) { set_le16(d, get_le16(d) >> v); return *this; }
|
||||
|
||||
operator unsigned () const { return get_le16(d); }
|
||||
}
|
||||
@@ -272,99 +341,168 @@ struct LE32
|
||||
LE32& operator = (unsigned v) { set_le32(d, v); return *this; }
|
||||
LE32& operator += (unsigned v) { set_le32(d, get_le32(d) + v); return *this; }
|
||||
LE32& operator -= (unsigned v) { set_le32(d, get_le32(d) - v); return *this; }
|
||||
LE32& operator *= (unsigned v) { set_le32(d, get_le32(d) * v); return *this; }
|
||||
LE32& operator /= (unsigned v) { set_le32(d, get_le32(d) / v); return *this; }
|
||||
LE32& operator &= (unsigned v) { set_le32(d, get_le32(d) & v); return *this; }
|
||||
LE32& operator |= (unsigned v) { set_le32(d, get_le32(d) | v); return *this; }
|
||||
LE32& operator ^= (unsigned v) { set_le32(d, get_le32(d) ^ v); return *this; }
|
||||
LE32& operator <<= (unsigned v) { set_le32(d, get_le32(d) << v); return *this; }
|
||||
LE32& operator >>= (unsigned v) { set_le32(d, get_le32(d) >> v); return *this; }
|
||||
|
||||
operator unsigned () const { return get_le32(d); }
|
||||
}
|
||||
__attribute_packed;
|
||||
|
||||
|
||||
struct LE64
|
||||
{
|
||||
unsigned char d[8];
|
||||
|
||||
LE64& operator = (acc_uint64l_t v) { set_le64(d, v); return *this; }
|
||||
LE64& operator += (acc_uint64l_t v) { set_le64(d, get_le64(d) + v); return *this; }
|
||||
LE64& operator -= (acc_uint64l_t v) { set_le64(d, get_le64(d) - v); return *this; }
|
||||
LE64& operator *= (acc_uint64l_t v) { set_le64(d, get_le64(d) * v); return *this; }
|
||||
LE64& operator /= (acc_uint64l_t v) { set_le64(d, get_le64(d) / v); return *this; }
|
||||
LE64& operator &= (acc_uint64l_t v) { set_le64(d, get_le64(d) & v); return *this; }
|
||||
LE64& operator |= (acc_uint64l_t v) { set_le64(d, get_le64(d) | v); return *this; }
|
||||
LE64& operator ^= (acc_uint64l_t v) { set_le64(d, get_le64(d) ^ v); return *this; }
|
||||
LE64& operator <<= (unsigned v) { set_le64(d, get_le64(d) << v); return *this; }
|
||||
LE64& operator >>= (unsigned v) { set_le64(d, get_le64(d) >> v); return *this; }
|
||||
|
||||
operator acc_uint64l_t () const { return get_le64(d); }
|
||||
}
|
||||
__attribute_packed;
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// global operators
|
||||
**************************************************************************/
|
||||
|
||||
inline bool operator < (const BE16& v1, const BE16& v2)
|
||||
{
|
||||
return (unsigned)v1 < (unsigned)v2;
|
||||
}
|
||||
|
||||
inline bool operator < (const BE32& v1, const BE32& v2)
|
||||
{
|
||||
return (unsigned)v1 < (unsigned)v2;
|
||||
}
|
||||
|
||||
inline bool operator < (const LE16& v1, const LE16& v2)
|
||||
{
|
||||
return (unsigned)v1 < (unsigned)v2;
|
||||
}
|
||||
|
||||
inline bool operator < (const LE32& v1, const LE32& v2)
|
||||
{
|
||||
return (unsigned)v1 < (unsigned)v2;
|
||||
}
|
||||
|
||||
|
||||
template <class T>
|
||||
inline T* operator + (T* ptr, const BE16& v) { return ptr + (unsigned) v; }
|
||||
template <class T>
|
||||
inline T* operator + (const BE16& v, T* ptr) { return ptr + (unsigned) v; }
|
||||
template <class T>
|
||||
inline T* operator - (T* ptr, const BE16& v) { return ptr - (unsigned) v; }
|
||||
|
||||
template <class T>
|
||||
inline T* operator + (T* ptr, const BE32& v) { return ptr + (unsigned) v; }
|
||||
template <class T>
|
||||
inline T* operator + (const BE32& v, T* ptr) { return ptr + (unsigned) v; }
|
||||
template <class T>
|
||||
inline T* operator - (T* ptr, const BE32& v) { return ptr - (unsigned) v; }
|
||||
|
||||
// these are not implemented on purpose and will cause link-time errors
|
||||
template <class T> T* operator + (T* ptr, const BE64& v);
|
||||
template <class T> T* operator + (const BE64& v, T* ptr);
|
||||
template <class T> T* operator - (T* ptr, const BE64& v);
|
||||
|
||||
template <class T>
|
||||
inline T* operator + (T* ptr, const LE16& v) { return ptr + (unsigned) v; }
|
||||
template <class T>
|
||||
inline T* operator + (const LE16& v, T* ptr) { return ptr + (unsigned) v; }
|
||||
template <class T>
|
||||
inline T* operator - (T* ptr, const LE16& v) { return ptr - (unsigned) v; }
|
||||
|
||||
template <class T>
|
||||
inline T* operator + (T* ptr, const LE32& v) { return ptr + (unsigned) v; }
|
||||
template <class T>
|
||||
inline T* operator + (const LE32& v, T* ptr) { return ptr + (unsigned) v; }
|
||||
template <class T>
|
||||
inline T* operator - (T* ptr, const LE32& v) { return ptr - (unsigned) v; }
|
||||
|
||||
// these are not implemented on purpose and will cause link-time errors
|
||||
template <class T> T* operator + (T* ptr, const LE64& v);
|
||||
template <class T> T* operator + (const LE64& v, T* ptr);
|
||||
template <class T> T* operator - (T* ptr, const LE64& v);
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// misc
|
||||
**************************************************************************/
|
||||
|
||||
// for use with qsort()
|
||||
int __acc_cdecl_qsort be16_compare(const void *e1, const void *e2);
|
||||
int __acc_cdecl_qsort be24_compare(const void *e1, const void *e2);
|
||||
int __acc_cdecl_qsort be32_compare(const void *e1, const void *e2);
|
||||
int __acc_cdecl_qsort le16_compare(const void *e1, const void *e2);
|
||||
int __acc_cdecl_qsort le24_compare(const void *e1, const void *e2);
|
||||
int __acc_cdecl_qsort le32_compare(const void *e1, const void *e2);
|
||||
int __acc_cdecl_qsort be16_compare_signed(const void *e1, const void *e2);
|
||||
int __acc_cdecl_qsort be24_compare_signed(const void *e1, const void *e2);
|
||||
int __acc_cdecl_qsort be32_compare_signed(const void *e1, const void *e2);
|
||||
int __acc_cdecl_qsort le16_compare_signed(const void *e1, const void *e2);
|
||||
int __acc_cdecl_qsort le24_compare_signed(const void *e1, const void *e2);
|
||||
int __acc_cdecl_qsort le32_compare_signed(const void *e1, const void *e2);
|
||||
int __acc_cdecl_qsort be16_compare(const void *, const void *);
|
||||
int __acc_cdecl_qsort be24_compare(const void *, const void *);
|
||||
int __acc_cdecl_qsort be32_compare(const void *, const void *);
|
||||
int __acc_cdecl_qsort be64_compare(const void *, const void *);
|
||||
int __acc_cdecl_qsort le16_compare(const void *, const void *);
|
||||
int __acc_cdecl_qsort le24_compare(const void *, const void *);
|
||||
int __acc_cdecl_qsort le32_compare(const void *, const void *);
|
||||
int __acc_cdecl_qsort le64_compare(const void *, const void *);
|
||||
int __acc_cdecl_qsort be16_compare_signed(const void *, const void *);
|
||||
int __acc_cdecl_qsort be24_compare_signed(const void *, const void *);
|
||||
int __acc_cdecl_qsort be32_compare_signed(const void *, const void *);
|
||||
int __acc_cdecl_qsort be64_compare_signed(const void *, const void *);
|
||||
int __acc_cdecl_qsort le16_compare_signed(const void *, const void *);
|
||||
int __acc_cdecl_qsort le24_compare_signed(const void *, const void *);
|
||||
int __acc_cdecl_qsort le32_compare_signed(const void *, const void *);
|
||||
int __acc_cdecl_qsort le64_compare_signed(const void *, const void *);
|
||||
|
||||
|
||||
// just for testing...
|
||||
#if 0 && (ACC_ARCH_AMD64 || ACC_ARCH_IA32) && (ACC_CC_GNUC >= 0x030200)
|
||||
typedef unsigned short LE16_unaligned __attribute__((__aligned__(1)));
|
||||
typedef acc_uint32e_t LE32_unaligned __attribute__((__aligned__(1)));
|
||||
# define LE16 LE16_unaligned
|
||||
# define LE32 LE32_unaligned
|
||||
#if !defined(ACC_CFG_NO_UNALIGNED)
|
||||
#if 0 && (ACC_ARCH_AMD64 || ACC_ARCH_I386) && (ACC_CC_GNUC >= 0x030200)
|
||||
typedef acc_uint16e_t LE16_unaligned __attribute__((__aligned__(1)));
|
||||
typedef acc_uint32e_t LE32_unaligned __attribute__((__aligned__(1)));
|
||||
# ifndef LE16
|
||||
# define LE16 LE16_unaligned
|
||||
# endif
|
||||
# ifndef LE32
|
||||
# define LE32 LE32_unaligned
|
||||
# endif
|
||||
#endif
|
||||
#if 0 && (ACC_ARCH_IA32) && (ACC_CC_INTELC)
|
||||
typedef __declspec(align(1)) unsigned short LE16_unaligned;
|
||||
typedef __declspec(align(1)) acc_uint32e_t LE32_unaligned;
|
||||
# define LE16 LE16_unaligned
|
||||
# define LE32 LE32_unaligned
|
||||
#if 0 && (ACC_ARCH_I386) && (ACC_CC_INTELC)
|
||||
typedef __declspec(align(1)) acc_uint16e_t LE16_unaligned;
|
||||
typedef __declspec(align(1)) acc_uint32e_t LE32_unaligned;
|
||||
# ifndef LE16
|
||||
# define LE16 LE16_unaligned
|
||||
# endif
|
||||
# ifndef LE32
|
||||
# define LE32 LE32_unaligned
|
||||
# endif
|
||||
#endif
|
||||
#if 0 && (ACC_ARCH_AMD64 || ACC_ARCH_IA32) && (ACC_CC_MSC) && (_MSC_VER >= 1200)
|
||||
typedef __declspec(align(1)) unsigned short LE16_unaligned;
|
||||
typedef __declspec(align(1)) acc_uint32e_t LE32_unaligned;
|
||||
# define LE16 LE16_unaligned
|
||||
# define LE32 LE32_unaligned
|
||||
#if 0 && (ACC_ARCH_AMD64 || ACC_ARCH_I386) && (ACC_CC_MSC) && (_MSC_VER >= 1200)
|
||||
typedef __declspec(align(1)) acc_uint16e_t LE16_unaligned;
|
||||
typedef __declspec(align(1)) acc_uint32e_t LE32_unaligned;
|
||||
# ifndef LE16
|
||||
# define LE16 LE16_unaligned
|
||||
# endif
|
||||
# ifndef LE32
|
||||
# define LE32 LE32_unaligned
|
||||
# endif
|
||||
# pragma warning(disable: 4244) // Wx: conversion, possible loss of data
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// Provide namespaces and classes to abtract endianness policies.
|
||||
//
|
||||
// CTP - Compile-Time Polymorphism (templates)
|
||||
// RTP - Run-Time Polymorphism (virtual functions)
|
||||
**************************************************************************/
|
||||
|
||||
// forward declarations
|
||||
namespace N_BELE_CTP {
|
||||
class BEPolicy; class LEPolicy;
|
||||
}
|
||||
namespace N_BELE_RTP {
|
||||
class AbstractPolicy;
|
||||
class BEPolicy; class LEPolicy;
|
||||
}
|
||||
|
||||
namespace N_BELE_CTP {
|
||||
#define BELE_CTP 1
|
||||
#include "bele_policy.h"
|
||||
#undef BELE_CTP
|
||||
}
|
||||
|
||||
namespace N_BELE_RTP {
|
||||
#define BELE_RTP 1
|
||||
#include "bele_policy.h"
|
||||
#undef BELE_RTP
|
||||
}
|
||||
|
||||
|
||||
#endif /* already included */
|
||||
|
||||
@@ -0,0 +1,273 @@
|
||||
/* bele_policy.h -- access memory in BigEndian and LittleEndian byte order
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
and/or modify them under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING.
|
||||
If not, write to the Free Software Foundation, Inc.,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __UPX_BELE_H
|
||||
# error "this is an internal include file"
|
||||
#endif
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
#if defined(BELE_CTP)
|
||||
// CTP - Compile-Time Polymorphism (templates)
|
||||
# define V static inline
|
||||
# define S static int __acc_cdecl_qsort
|
||||
# define C
|
||||
#elif defined(BELE_RTP)
|
||||
// RTP - Run-Time Polymorphism (virtual functions)
|
||||
# define V virtual
|
||||
# define S virtual int
|
||||
# define C const
|
||||
#else
|
||||
# error
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(BELE_RTP)
|
||||
struct AbstractPolicy
|
||||
{
|
||||
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;
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
struct BEPolicy
|
||||
#if defined(BELE_RTP)
|
||||
: public AbstractPolicy
|
||||
#endif
|
||||
{
|
||||
#if defined(BELE_CTP)
|
||||
typedef N_BELE_RTP::BEPolicy RTP_Policy;
|
||||
enum { isBE = 1, isLE = 0 };
|
||||
#elif defined(BELE_RTP)
|
||||
typedef N_BELE_CTP::BEPolicy CTP_Policy;
|
||||
V bool isBE() C { return CTP_Policy::isBE; }
|
||||
V bool isLE() C { return CTP_Policy::isLE; }
|
||||
#endif
|
||||
|
||||
typedef BE16 U16;
|
||||
typedef BE32 U32;
|
||||
typedef BE64 U64;
|
||||
|
||||
V unsigned get16(const void *p) C
|
||||
{ return get_be16(p); }
|
||||
V unsigned get24(const void *p) C
|
||||
{ return get_be24(p); }
|
||||
V unsigned get32(const void *p) C
|
||||
{ return get_be32(p); }
|
||||
V acc_uint64l_t get64(const void *p) C
|
||||
{ return get_be64(p); }
|
||||
|
||||
V void set16(void *p, unsigned v) C
|
||||
{ set_be16(p, v); }
|
||||
V void set24(void *p, unsigned v) C
|
||||
{ set_be24(p, v); }
|
||||
V void set32(void *p, unsigned v) C
|
||||
{ set_be32(p, v); }
|
||||
V void set64(void *p, acc_uint64l_t v) C
|
||||
{ set_be64(p, v); }
|
||||
|
||||
V unsigned get16_signed(const void *p) C
|
||||
{ return get_be16_signed(p); }
|
||||
V unsigned get24_signed(const void *p) C
|
||||
{ return get_be24_signed(p); }
|
||||
V unsigned get32_signed(const void *p) C
|
||||
{ return get_be32_signed(p); }
|
||||
V acc_uint64l_t get64_signed(const void *p) C
|
||||
{ return get_be64_signed(p); }
|
||||
|
||||
S u16_compare(const void *a, const void *b) C
|
||||
{ return be16_compare(a, b); }
|
||||
S u24_compare(const void *a, const void *b) C
|
||||
{ return be24_compare(a, b); }
|
||||
S u32_compare(const void *a, const void *b) C
|
||||
{ return be32_compare(a, b); }
|
||||
S u64_compare(const void *a, const void *b) C
|
||||
{ return be64_compare(a, b); }
|
||||
|
||||
S u16_compare_signed(const void *a, const void *b) C
|
||||
{ return be16_compare_signed(a, b); }
|
||||
S u24_compare_signed(const void *a, const void *b) C
|
||||
{ return be24_compare_signed(a, b); }
|
||||
S u32_compare_signed(const void *a, const void *b) C
|
||||
{ return be32_compare_signed(a, b); }
|
||||
S u64_compare_signed(const void *a, const void *b) C
|
||||
{ return be64_compare_signed(a, b); }
|
||||
|
||||
static void compileTimeAssertions() {
|
||||
COMPILE_TIME_ASSERT(sizeof(U16) == 2)
|
||||
COMPILE_TIME_ASSERT(sizeof(U32) == 4)
|
||||
COMPILE_TIME_ASSERT(sizeof(U64) == 8)
|
||||
COMPILE_TIME_ASSERT_ALIGNOF(U16, char)
|
||||
COMPILE_TIME_ASSERT_ALIGNOF(U32, char)
|
||||
COMPILE_TIME_ASSERT_ALIGNOF(U64, char)
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct LEPolicy
|
||||
#if defined(BELE_RTP)
|
||||
: public AbstractPolicy
|
||||
#endif
|
||||
{
|
||||
#if defined(BELE_CTP)
|
||||
typedef N_BELE_RTP::LEPolicy RTP_Policy;
|
||||
enum { isBE = 0, isLE = 1 };
|
||||
#elif defined(BELE_RTP)
|
||||
typedef N_BELE_CTP::LEPolicy CTP_Policy;
|
||||
V bool isBE() C { return CTP_Policy::isBE; }
|
||||
V bool isLE() C { return CTP_Policy::isLE; }
|
||||
#endif
|
||||
|
||||
typedef LE16 U16;
|
||||
typedef LE32 U32;
|
||||
typedef LE64 U64;
|
||||
|
||||
V unsigned get16(const void *p) C
|
||||
{ return get_le16(p); }
|
||||
V unsigned get24(const void *p) C
|
||||
{ return get_le24(p); }
|
||||
V unsigned get32(const void *p) C
|
||||
{ return get_le32(p); }
|
||||
V acc_uint64l_t get64(const void *p) C
|
||||
{ return get_le64(p); }
|
||||
|
||||
V void set16(void *p, unsigned v) C
|
||||
{ set_le16(p, v); }
|
||||
V void set24(void *p, unsigned v) C
|
||||
{ set_le24(p, v); }
|
||||
V void set32(void *p, unsigned v) C
|
||||
{ set_le32(p, v); }
|
||||
V void set64(void *p, acc_uint64l_t v) C
|
||||
{ set_le64(p, v); }
|
||||
|
||||
V unsigned get16_signed(const void *p) C
|
||||
{ return get_le16_signed(p); }
|
||||
V unsigned get24_signed(const void *p) C
|
||||
{ return get_le24_signed(p); }
|
||||
V unsigned get32_signed(const void *p) C
|
||||
{ return get_le32_signed(p); }
|
||||
V acc_uint64l_t get64_signed(const void *p) C
|
||||
{ return get_le64_signed(p); }
|
||||
|
||||
S u16_compare(const void *a, const void *b) C
|
||||
{ return le16_compare(a, b); }
|
||||
S u24_compare(const void *a, const void *b) C
|
||||
{ return le24_compare(a, b); }
|
||||
S u32_compare(const void *a, const void *b) C
|
||||
{ return le32_compare(a, b); }
|
||||
S u64_compare(const void *a, const void *b) C
|
||||
{ return le64_compare(a, b); }
|
||||
|
||||
S u16_compare_signed(const void *a, const void *b) C
|
||||
{ return le16_compare_signed(a, b); }
|
||||
S u24_compare_signed(const void *a, const void *b) C
|
||||
{ return le24_compare_signed(a, b); }
|
||||
S u32_compare_signed(const void *a, const void *b) C
|
||||
{ return le32_compare_signed(a, b); }
|
||||
S u64_compare_signed(const void *a, const void *b) C
|
||||
{ return le64_compare_signed(a, b); }
|
||||
|
||||
static void compileTimeAssertions() {
|
||||
COMPILE_TIME_ASSERT(sizeof(U16) == 2)
|
||||
COMPILE_TIME_ASSERT(sizeof(U32) == 4)
|
||||
COMPILE_TIME_ASSERT(sizeof(U64) == 8)
|
||||
COMPILE_TIME_ASSERT_ALIGNOF(U16, char)
|
||||
COMPILE_TIME_ASSERT_ALIGNOF(U32, char)
|
||||
COMPILE_TIME_ASSERT_ALIGNOF(U64, char)
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#if (ACC_ABI_BIG_ENDIAN)
|
||||
typedef BEPolicy HostPolicy;
|
||||
#elif (ACC_ABI_LITTLE_ENDIAN)
|
||||
typedef LEPolicy HostPolicy;
|
||||
#else
|
||||
# error "ACC_ABI_ENDIAN"
|
||||
#endif
|
||||
|
||||
|
||||
#if 0 /* UNUSED */
|
||||
struct HostAlignedPolicy
|
||||
{
|
||||
#if defined(BELE_CTP)
|
||||
enum { isBE = HostPolicy::isBE, isLE = HostPolicy::isLE };
|
||||
#endif
|
||||
|
||||
typedef acc_uint16e_t U16;
|
||||
typedef acc_uint32e_t U32;
|
||||
typedef acc_uint64l_t U64;
|
||||
|
||||
static void compileTimeAssertions() {
|
||||
COMPILE_TIME_ASSERT(sizeof(U16) == 2)
|
||||
COMPILE_TIME_ASSERT(sizeof(U32) == 4)
|
||||
COMPILE_TIME_ASSERT(sizeof(U64) == 8)
|
||||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
#undef V
|
||||
#undef S
|
||||
#undef C
|
||||
|
||||
|
||||
/*
|
||||
vi:ts=4:et:nowrap
|
||||
*/
|
||||
|
||||
+2
-2
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2004 Laszlo Molnar
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
|
||||
+3
-3
@@ -2,8 +2,8 @@
|
||||
|
||||
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) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -72,7 +72,7 @@ static void print0(FILE *f, const char *s)
|
||||
}
|
||||
|
||||
|
||||
static upx_bool intro(FILE *f)
|
||||
static bool intro(FILE *f)
|
||||
{
|
||||
UNUSED(f);
|
||||
return 0;
|
||||
|
||||
+3
-3
@@ -2,8 +2,8 @@
|
||||
|
||||
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) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -124,7 +124,7 @@ static int set_fg(FILE *f, int fg)
|
||||
}
|
||||
|
||||
|
||||
static upx_bool intro(FILE *f)
|
||||
static bool intro(FILE *f)
|
||||
{
|
||||
if (con == me)
|
||||
init(f,-1,-1);
|
||||
|
||||
+3
-3
@@ -2,8 +2,8 @@
|
||||
|
||||
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) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -58,7 +58,7 @@ static void print0(FILE *f, const char *s)
|
||||
}
|
||||
|
||||
|
||||
static upx_bool intro(FILE *f)
|
||||
static bool intro(FILE *f)
|
||||
{
|
||||
UNUSED(f);
|
||||
return 0;
|
||||
|
||||
+3
-3
@@ -2,8 +2,8 @@
|
||||
|
||||
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) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -295,7 +295,7 @@ static void print0(FILE *f, const char *ss)
|
||||
}
|
||||
|
||||
|
||||
static upx_bool intro(FILE *f)
|
||||
static bool intro(FILE *f)
|
||||
{
|
||||
UNUSED(f);
|
||||
#if defined(USE_FRAMES)
|
||||
|
||||
-242
@@ -1,242 +0,0 @@
|
||||
/* compress.ch --
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2004 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
and/or modify them under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING.
|
||||
If not, write to the Free Software Foundation, Inc.,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
||||
*/
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
#if defined(upx_adler32)
|
||||
unsigned upx_adler32(const void *buf, unsigned len, unsigned adler)
|
||||
{
|
||||
if (len == 0)
|
||||
return adler;
|
||||
assert(buf != NULL);
|
||||
return ucl_adler32(adler, (const ucl_bytep)buf, len);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(upx_crc32)
|
||||
unsigned upx_crc32(const void *buf, unsigned len, unsigned crc)
|
||||
{
|
||||
if (len == 0)
|
||||
return crc;
|
||||
assert(buf != NULL);
|
||||
return ucl_crc32(crc, (const ucl_bytep)buf, len);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
#if defined(upx_compress)
|
||||
|
||||
int upx_compress ( const upx_bytep src, upx_uint src_len,
|
||||
upx_bytep dst, upx_uintp dst_len,
|
||||
upx_progress_callback_t *cb,
|
||||
int method, int level,
|
||||
const struct upx_compress_config_t *conf_parm,
|
||||
upx_uintp result )
|
||||
{
|
||||
struct upx_compress_config_t conf;
|
||||
upx_uint result_buffer[16];
|
||||
int r = UPX_E_ERROR;
|
||||
|
||||
assert(level > 0);
|
||||
memset(&conf, 0xff, sizeof(conf));
|
||||
if (conf_parm)
|
||||
conf = *conf_parm; // struct copy
|
||||
if (!result)
|
||||
result = result_buffer;
|
||||
|
||||
// assume no info available - fill in worst case results
|
||||
//result[0] = 1; // min_offset_found - NOT USED
|
||||
result[1] = src_len - 1; // max_offset_found
|
||||
//result[2] = 2; // min_match_found - NOT USED
|
||||
result[3] = src_len - 1; // max_match_found
|
||||
//result[4] = 1; // min_run_found - NOT USED
|
||||
result[5] = src_len; // max_run_found
|
||||
result[6] = 1; // first_offset_found
|
||||
//result[7] = 999999; // same_match_offsets_found - NOT USED
|
||||
|
||||
// prepare bit-buffer settings
|
||||
conf.bb_endian = 0;
|
||||
conf.bb_size = 0;
|
||||
if (method >= M_NRV2B_LE32 && method <= M_NRV2E_LE16)
|
||||
{
|
||||
int n = (method - M_NRV2B_LE32) % 3;
|
||||
if (n == 0)
|
||||
conf.bb_size = 32;
|
||||
else if (n == 1)
|
||||
conf.bb_size = 8;
|
||||
else
|
||||
conf.bb_size = 16;
|
||||
}
|
||||
else
|
||||
throwInternalError("unknown compression method");
|
||||
|
||||
// optimize compression parms
|
||||
if (level <= 3 && conf.max_offset == UPX_UINT_MAX)
|
||||
conf.max_offset = 8*1024-1;
|
||||
else if (level == 4 && conf.max_offset == UPX_UINT_MAX)
|
||||
conf.max_offset = 32*1024-1;
|
||||
|
||||
if M_IS_NRV2B(method)
|
||||
r = ucl_nrv2b_99_compress(src, src_len, dst, dst_len,
|
||||
cb, level, &conf, result);
|
||||
else if M_IS_NRV2D(method)
|
||||
r = ucl_nrv2d_99_compress(src, src_len, dst, dst_len,
|
||||
cb, level, &conf, result);
|
||||
#if defined(ALG_NRV2E)
|
||||
else if M_IS_NRV2E(method)
|
||||
r = ucl_nrv2e_99_compress(src, src_len, dst, dst_len,
|
||||
cb, level, &conf, result);
|
||||
#endif
|
||||
else
|
||||
throwInternalError("unknown compression method");
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
#endif /* upx_compress */
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
#if defined(upx_decompress)
|
||||
|
||||
int upx_decompress ( const upx_bytep src, upx_uint src_len,
|
||||
upx_bytep dst, upx_uintp dst_len,
|
||||
int method )
|
||||
{
|
||||
int r = UPX_E_ERROR;
|
||||
|
||||
switch (method)
|
||||
{
|
||||
case M_NRV2B_8:
|
||||
r = ucl_nrv2b_decompress_safe_8(src,src_len,dst,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2B_LE16:
|
||||
r = ucl_nrv2b_decompress_safe_le16(src,src_len,dst,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2B_LE32:
|
||||
r = ucl_nrv2b_decompress_safe_le32(src,src_len,dst,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2D_8:
|
||||
r = ucl_nrv2d_decompress_safe_8(src,src_len,dst,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2D_LE16:
|
||||
r = ucl_nrv2d_decompress_safe_le16(src,src_len,dst,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2D_LE32:
|
||||
r = ucl_nrv2d_decompress_safe_le32(src,src_len,dst,dst_len,NULL);
|
||||
break;
|
||||
#if defined(ALG_NRV2E)
|
||||
case M_NRV2E_8:
|
||||
r = ucl_nrv2e_decompress_safe_8(src,src_len,dst,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2E_LE16:
|
||||
r = ucl_nrv2e_decompress_safe_le16(src,src_len,dst,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2E_LE32:
|
||||
r = ucl_nrv2e_decompress_safe_le32(src,src_len,dst,dst_len,NULL);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
throwInternalError("unknown decompression method");
|
||||
break;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
#endif /* upx_decompress */
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
#if defined(upx_test_overlap)
|
||||
|
||||
int upx_test_overlap ( const upx_bytep buf, upx_uint src_off,
|
||||
upx_uint src_len, upx_uintp dst_len,
|
||||
int method )
|
||||
{
|
||||
int r = UPX_E_ERROR;
|
||||
|
||||
switch (method)
|
||||
{
|
||||
case M_NRV2B_8:
|
||||
r = ucl_nrv2b_test_overlap_8(buf,src_off,src_len,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2B_LE16:
|
||||
r = ucl_nrv2b_test_overlap_le16(buf,src_off,src_len,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2B_LE32:
|
||||
r = ucl_nrv2b_test_overlap_le32(buf,src_off,src_len,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2D_8:
|
||||
r = ucl_nrv2d_test_overlap_8(buf,src_off,src_len,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2D_LE16:
|
||||
r = ucl_nrv2d_test_overlap_le16(buf,src_off,src_len,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2D_LE32:
|
||||
r = ucl_nrv2d_test_overlap_le32(buf,src_off,src_len,dst_len,NULL);
|
||||
break;
|
||||
#if defined(ALG_NRV2E)
|
||||
case M_NRV2E_8:
|
||||
r = ucl_nrv2e_test_overlap_8(buf,src_off,src_len,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2E_LE16:
|
||||
r = ucl_nrv2e_test_overlap_le16(buf,src_off,src_len,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2E_LE32:
|
||||
r = ucl_nrv2e_test_overlap_le32(buf,src_off,src_len,dst_len,NULL);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
throwInternalError("unknown decompression method");
|
||||
break;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
#endif /* upx_test_overlap */
|
||||
|
||||
|
||||
/*
|
||||
vi:ts=4:et:nowrap
|
||||
*/
|
||||
|
||||
+182
-13
@@ -2,8 +2,8 @@
|
||||
|
||||
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) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -27,23 +27,192 @@
|
||||
|
||||
|
||||
#include "conf.h"
|
||||
#include "compress.h"
|
||||
#include "mem.h"
|
||||
#include <zlib.h>
|
||||
|
||||
|
||||
#if defined(WITH_NRV)
|
||||
# include "compress_nrv.ch"
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
unsigned upx_adler32(const void *buf, unsigned len, unsigned adler)
|
||||
{
|
||||
if (len == 0)
|
||||
return adler;
|
||||
assert(buf != NULL);
|
||||
#if 0
|
||||
return adler32(adler, (const Bytef *) buf, len); // zlib
|
||||
#elif defined(WITH_UCL)
|
||||
# define upx_adler32 upx_adler32
|
||||
//# define upx_crc32 upx_crc32
|
||||
# define upx_compress upx_compress
|
||||
# define upx_decompress upx_decompress
|
||||
# if (UPX_VERSION_HEX >= 0x019000)
|
||||
# define ALG_NRV2E
|
||||
# define upx_test_overlap upx_test_overlap
|
||||
# endif
|
||||
# include "compress.ch"
|
||||
return ucl_adler32(adler, (const ucl_bytep) buf, len);
|
||||
#else
|
||||
# error
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#if 0 /* UNUSED */
|
||||
unsigned upx_crc32(const void *buf, unsigned len, unsigned crc)
|
||||
{
|
||||
if (len == 0)
|
||||
return crc;
|
||||
assert(buf != NULL);
|
||||
#if 0
|
||||
return crc32(crc, (const Bytef *) buf, len); // zlib
|
||||
#elif defined(WITH_UCL)
|
||||
return ucl_crc32(crc, (const ucl_bytep) buf, len);
|
||||
#else
|
||||
# error
|
||||
#endif
|
||||
}
|
||||
#endif /* UNUSED */
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
int upx_compress ( const upx_bytep src, unsigned src_len,
|
||||
upx_bytep dst, unsigned* dst_len,
|
||||
upx_callback_p cb,
|
||||
int method, int level,
|
||||
const upx_compress_config_t *cconf,
|
||||
upx_compress_result_t *cresult )
|
||||
{
|
||||
int r = UPX_E_ERROR;
|
||||
upx_compress_result_t cresult_buffer;
|
||||
|
||||
assert(method > 0); assert(level > 0);
|
||||
|
||||
#if 1
|
||||
// set available bytes in dst
|
||||
if (*dst_len == 0)
|
||||
*dst_len = MemBuffer::getSizeForCompression(src_len);
|
||||
#else
|
||||
// force users to provide *dst_len
|
||||
assert(*dst_len != 0);
|
||||
#endif
|
||||
// for UPX, we always require a reasonably sized outbut buffer
|
||||
assert(*dst_len >= MemBuffer::getSizeForCompression(src_len));
|
||||
|
||||
if (!cresult)
|
||||
cresult = &cresult_buffer;
|
||||
memset(cresult, 0, sizeof(*cresult));
|
||||
#if 1
|
||||
// debug
|
||||
cresult->method = method;
|
||||
cresult->level = level;
|
||||
cresult->u_len = src_len;
|
||||
cresult->c_len = 0;
|
||||
#endif
|
||||
|
||||
if (method < 0) {
|
||||
}
|
||||
#if defined(WITH_LZMA)
|
||||
else if (M_IS_LZMA(method))
|
||||
r = upx_lzma_compress(src, src_len, dst, dst_len,
|
||||
cb, method, level, cconf, cresult);
|
||||
#endif
|
||||
#if defined(WITH_NRV)
|
||||
else if (M_IS_NRV2B(method) || M_IS_NRV2D(method) || M_IS_NRV2E(method))
|
||||
r = upx_nrv_compress(src, src_len, dst, dst_len,
|
||||
cb, method, level, cconf, cresult);
|
||||
#endif
|
||||
#if defined(WITH_UCL)
|
||||
else if (M_IS_NRV2B(method) || M_IS_NRV2D(method) || M_IS_NRV2E(method))
|
||||
r = upx_ucl_compress(src, src_len, dst, dst_len,
|
||||
cb, method, level, cconf, cresult);
|
||||
#endif
|
||||
else {
|
||||
throwInternalError("unknown compression method");
|
||||
}
|
||||
|
||||
#if 1
|
||||
// debug
|
||||
cresult->c_len = *dst_len;
|
||||
#endif
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
int upx_decompress ( const upx_bytep src, unsigned src_len,
|
||||
upx_bytep dst, unsigned* dst_len,
|
||||
int method,
|
||||
const upx_compress_result_t *cresult )
|
||||
{
|
||||
int r = UPX_E_ERROR;
|
||||
|
||||
assert(*dst_len > 0);
|
||||
assert(src_len < *dst_len); // must be compressed
|
||||
|
||||
if (cresult && cresult->method == 0)
|
||||
cresult = NULL;
|
||||
|
||||
if (method < 0) {
|
||||
}
|
||||
#if defined(WITH_LZMA)
|
||||
else if (M_IS_LZMA(method))
|
||||
r = upx_lzma_decompress(src, src_len, dst, dst_len, method, cresult);
|
||||
#endif
|
||||
#if defined(WITH_NRV)
|
||||
else if (M_IS_NRV2B(method) || M_IS_NRV2D(method) || M_IS_NRV2E(method))
|
||||
r = upx_nrv_decompress(src, src_len, dst, dst_len, method, cresult);
|
||||
#endif
|
||||
#if defined(WITH_UCL)
|
||||
else if (M_IS_NRV2B(method) || M_IS_NRV2D(method) || M_IS_NRV2E(method))
|
||||
r = upx_ucl_decompress(src, src_len, dst, dst_len, method, cresult);
|
||||
#endif
|
||||
else {
|
||||
throwInternalError("unknown decompression method");
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
int upx_test_overlap ( const upx_bytep buf, unsigned src_off,
|
||||
unsigned src_len, unsigned* dst_len,
|
||||
int method,
|
||||
const upx_compress_result_t *cresult )
|
||||
{
|
||||
int r = UPX_E_ERROR;
|
||||
|
||||
if (cresult && cresult->method == 0)
|
||||
cresult = NULL;
|
||||
|
||||
assert(*dst_len > 0);
|
||||
assert(src_len < *dst_len); // must be compressed
|
||||
unsigned overlap_overhead = src_off + src_len - *dst_len;
|
||||
assert((int)overlap_overhead > 0);
|
||||
|
||||
if (method < 0) {
|
||||
}
|
||||
#if defined(WITH_LZMA)
|
||||
else if (M_IS_LZMA(method))
|
||||
r = upx_lzma_test_overlap(buf, src_off, src_len, dst_len, method, cresult);
|
||||
#endif
|
||||
#if defined(WITH_NRV)
|
||||
else if (M_IS_NRV2B(method) || M_IS_NRV2D(method) || M_IS_NRV2E(method))
|
||||
r = upx_nrv_test_overlap(buf, src_off, src_len, dst_len, method, cresult);
|
||||
#endif
|
||||
#if defined(WITH_UCL)
|
||||
else if (M_IS_NRV2B(method) || M_IS_NRV2D(method) || M_IS_NRV2E(method))
|
||||
r = upx_ucl_test_overlap(buf, src_off, src_len, dst_len, method, cresult);
|
||||
#endif
|
||||
else {
|
||||
throwInternalError("unknown decompression method");
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
/* compress.h --
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
and/or modify them under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING.
|
||||
If not, write to the Free Software Foundation, Inc.,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __UPX_COMPRESS_H
|
||||
#define __UPX_COMPRESS_H
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
#if defined(WITH_LZMA)
|
||||
int upx_lzma_compress ( const upx_bytep src, unsigned src_len,
|
||||
upx_bytep dst, unsigned* dst_len,
|
||||
upx_callback_p cb,
|
||||
int method, int level,
|
||||
const upx_compress_config_t *cconf,
|
||||
upx_compress_result_t *cresult );
|
||||
int upx_lzma_decompress ( const upx_bytep src, unsigned src_len,
|
||||
upx_bytep dst, unsigned* dst_len,
|
||||
int method,
|
||||
const upx_compress_result_t *cresult );
|
||||
int upx_lzma_test_overlap ( const upx_bytep buf, unsigned src_off,
|
||||
unsigned src_len, unsigned* dst_len,
|
||||
int method,
|
||||
const upx_compress_result_t *cresult );
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(WITH_NRV)
|
||||
int upx_nrv_compress ( const upx_bytep src, unsigned src_len,
|
||||
upx_bytep dst, unsigned* dst_len,
|
||||
upx_callback_p cb,
|
||||
int method, int level,
|
||||
const upx_compress_config_t *cconf,
|
||||
upx_compress_result_t *cresult );
|
||||
int upx_nrv_decompress ( const upx_bytep src, unsigned src_len,
|
||||
upx_bytep dst, unsigned* dst_len,
|
||||
int method,
|
||||
const upx_compress_result_t *cresult );
|
||||
int upx_nrv_test_overlap ( const upx_bytep buf, unsigned src_off,
|
||||
unsigned src_len, unsigned* dst_len,
|
||||
int method,
|
||||
const upx_compress_result_t *cresult );
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(WITH_UCL)
|
||||
int upx_ucl_compress ( const upx_bytep src, unsigned src_len,
|
||||
upx_bytep dst, unsigned* dst_len,
|
||||
upx_callback_p cb,
|
||||
int method, int level,
|
||||
const upx_compress_config_t *cconf,
|
||||
upx_compress_result_t *cresult );
|
||||
int upx_ucl_decompress ( const upx_bytep src, unsigned src_len,
|
||||
upx_bytep dst, unsigned* dst_len,
|
||||
int method,
|
||||
const upx_compress_result_t *cresult );
|
||||
int upx_ucl_test_overlap ( const upx_bytep buf, unsigned src_off,
|
||||
unsigned src_len, unsigned* dst_len,
|
||||
int method,
|
||||
const upx_compress_result_t *cresult );
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* already included */
|
||||
|
||||
|
||||
/*
|
||||
vi:ts=4:et
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,450 @@
|
||||
/* compress_lzma.cpp --
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
and/or modify them under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING.
|
||||
If not, write to the Free Software Foundation, Inc.,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
||||
*/
|
||||
|
||||
|
||||
#include "conf.h"
|
||||
#include "compress.h"
|
||||
#if !defined(WITH_LZMA)
|
||||
extern int compress_lzma_dummy;
|
||||
int compress_lzma_dummy = 0;
|
||||
#else
|
||||
|
||||
|
||||
// INFO: the LZMA SDK is covered by a permissive license which allows
|
||||
// using unmodified LZMA source code in UPX and the UPX stubs.
|
||||
// See SPECIAL EXCEPTION below.
|
||||
//
|
||||
// Quoting from lzma-4.43/lzma.txt:
|
||||
//
|
||||
// LICENSE
|
||||
// -------
|
||||
//
|
||||
// LZMA SDK is available under any of the following licenses:
|
||||
//
|
||||
// 1) GNU Lesser General Public License (GNU LGPL)
|
||||
// 2) Common Public License (CPL)
|
||||
// 3) Simplified license for unmodified code (read SPECIAL EXCEPTION)
|
||||
// 4) Proprietary license
|
||||
//
|
||||
// It means that you can select one of these four options and follow rules
|
||||
// of that license.
|
||||
//
|
||||
// 1,2) GNU LGPL and CPL licenses are pretty similar and both these
|
||||
// licenses are classified as
|
||||
// - "Free software licenses" at http://www.gnu.org/
|
||||
// - "OSI-approved" at http://www.opensource.org/
|
||||
//
|
||||
// 3) SPECIAL EXCEPTION
|
||||
//
|
||||
// Igor Pavlov, as the author of this code, expressly permits you
|
||||
// to statically or dynamically link your code (or bind by name)
|
||||
// to the files from LZMA SDK without subjecting your linked
|
||||
// code to the terms of the CPL or GNU LGPL.
|
||||
// Any modifications or additions to files from LZMA SDK, however,
|
||||
// are subject to the GNU LGPL or CPL terms.
|
||||
//
|
||||
// SPECIAL EXCEPTION allows you to use LZMA SDK in applications with closed code,
|
||||
// while you keep LZMA SDK code unmodified.
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// cruft because of pseudo-COM layer
|
||||
**************************************************************************/
|
||||
|
||||
#undef USE_LZMA_PROPERTIES
|
||||
|
||||
#undef MSDOS
|
||||
#undef OS2
|
||||
#undef _WIN32
|
||||
#undef _WIN32_WCE
|
||||
#undef COMPRESS_MF_MT
|
||||
#undef _NO_EXCEPTIONS
|
||||
#include "C/Common/MyInitGuid.h"
|
||||
//#include "C/7zip/Compress/LZMA/LZMADecoder.h"
|
||||
#include "C/7zip/Compress/LZMA/LZMAEncoder.h"
|
||||
|
||||
namespace MyLzma {
|
||||
|
||||
struct InStreamRam: public ISequentialInStream, public CMyUnknownImp
|
||||
{
|
||||
MY_UNKNOWN_IMP
|
||||
const Byte *Data; size_t Size; size_t Pos;
|
||||
void Init(const Byte *data, size_t size) {
|
||||
Data = data; Size = size; Pos = 0;
|
||||
}
|
||||
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize);
|
||||
};
|
||||
|
||||
STDMETHODIMP InStreamRam::Read(void *data, UInt32 size, UInt32 *processedSize)
|
||||
{
|
||||
UInt32 remain = Size - Pos;
|
||||
if (size > remain) size = remain;
|
||||
memmove(data, Data + Pos, size);
|
||||
Pos += size;
|
||||
if (processedSize != NULL) *processedSize = size;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
struct OutStreamRam : public ISequentialOutStream, public CMyUnknownImp
|
||||
{
|
||||
MY_UNKNOWN_IMP
|
||||
Byte *Data; size_t Size; size_t Pos; bool Overflow;
|
||||
void Init(Byte *data, size_t size) {
|
||||
Data = data; Size = size; Pos = 0; Overflow = false;
|
||||
}
|
||||
HRESULT WriteByte(Byte b) {
|
||||
if (Pos >= Size) { Overflow = true; return E_FAIL; }
|
||||
Data[Pos++] = b;
|
||||
return S_OK;
|
||||
}
|
||||
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
|
||||
};
|
||||
|
||||
STDMETHODIMP OutStreamRam::Write(const void *data, UInt32 size, UInt32 *processedSize)
|
||||
{
|
||||
UInt32 i;
|
||||
for (i = 0; i < size && Pos < Size; i++)
|
||||
Data[Pos++] = ((const Byte *)data)[i];
|
||||
if (processedSize != NULL) *processedSize = i;
|
||||
if (i != size) { Overflow = true; return E_FAIL; }
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
struct ProgressInfo : public ICompressProgressInfo, public CMyUnknownImp
|
||||
{
|
||||
MY_UNKNOWN_IMP
|
||||
STDMETHOD(SetRatioInfo)(const UInt64 *inSize, const UInt64 *outSize);
|
||||
upx_callback_p cb;
|
||||
};
|
||||
|
||||
STDMETHODIMP ProgressInfo::SetRatioInfo(const UInt64 *inSize, const UInt64 *outSize)
|
||||
{
|
||||
if (cb && cb->nprogress)
|
||||
cb->nprogress(cb, (unsigned) *inSize, (unsigned) *outSize);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
|
||||
int upx_lzma_compress ( const upx_bytep src, unsigned src_len,
|
||||
upx_bytep dst, unsigned* dst_len,
|
||||
upx_callback_p cb,
|
||||
int method, int level,
|
||||
const upx_compress_config_t *cconf_parm,
|
||||
upx_compress_result_t *cresult )
|
||||
{
|
||||
assert(method == M_LZMA);
|
||||
assert(level > 0); assert(cresult != NULL);
|
||||
|
||||
int r = UPX_E_ERROR;
|
||||
HRESULT rh;
|
||||
lzma_compress_result_t *res = &cresult->result_lzma;
|
||||
|
||||
MyLzma::InStreamRam is; is.AddRef();
|
||||
MyLzma::OutStreamRam os; os.AddRef();
|
||||
is.Init(src, src_len);
|
||||
os.Init(dst, *dst_len);
|
||||
|
||||
MyLzma::ProgressInfo progress; progress.AddRef();
|
||||
progress.cb = cb;
|
||||
|
||||
NCompress::NLZMA::CEncoder enc;
|
||||
const PROPID propIDs[7] = {
|
||||
NCoderPropID::kPosStateBits, // 0 pb _posStateBits(2)
|
||||
NCoderPropID::kLitPosBits, // 1 lp _numLiteralPosStateBits(0)
|
||||
NCoderPropID::kLitContextBits, // 2 lc _numLiteralContextBits(3)
|
||||
NCoderPropID::kDictionarySize, // 3
|
||||
NCoderPropID::kAlgorithm, // 4 _fastmode
|
||||
NCoderPropID::kNumFastBytes, // 5
|
||||
NCoderPropID::kMatchFinderCycles // 6
|
||||
};
|
||||
PROPVARIANT pr[7];
|
||||
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;
|
||||
|
||||
// setup defaults
|
||||
pr[0].uintVal = 2; // 0..4
|
||||
pr[1].uintVal = 0; // 0..4
|
||||
pr[2].uintVal = 3; // 0..8
|
||||
pr[3].uintVal = 1024 * 1024;
|
||||
pr[4].uintVal = 2;
|
||||
pr[5].uintVal = 64; // 5..
|
||||
pr[6].uintVal = 0;
|
||||
#if 0
|
||||
// DEBUG - set sizes so that we use a maxmimum amount of stack.
|
||||
// These settings cause res->num_probs == 3147574, i.e. we will
|
||||
// need about 6 MB of stack during runtime decompression.
|
||||
pr[1].uintVal = 4;
|
||||
pr[2].uintVal = 8;
|
||||
#endif
|
||||
|
||||
// FIXME: tune these settings according to level
|
||||
switch (level)
|
||||
{
|
||||
case 1:
|
||||
pr[3].uintVal = 256 * 1024;
|
||||
pr[4].uintVal = 0;
|
||||
break;
|
||||
case 2:
|
||||
break;
|
||||
case 3:
|
||||
break;
|
||||
case 4:
|
||||
break;
|
||||
case 5:
|
||||
break;
|
||||
case 6:
|
||||
break;
|
||||
case 7:
|
||||
break;
|
||||
case 8:
|
||||
break;
|
||||
case 9:
|
||||
pr[3].uintVal = 8 * 1024 * 1024;
|
||||
break;
|
||||
case 10:
|
||||
pr[3].uintVal = src_len;
|
||||
break;
|
||||
default:
|
||||
goto error;
|
||||
}
|
||||
|
||||
// limit dictionary size
|
||||
if (pr[3].uintVal > src_len)
|
||||
pr[3].uintVal = src_len;
|
||||
|
||||
// limit num_probs
|
||||
if (cconf_parm && cconf_parm->conf_lzma.max_num_probs)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
unsigned n = 1846 + (768 << (pr[2].uintVal + pr[1].uintVal));
|
||||
if (n <= cconf_parm->conf_lzma.max_num_probs)
|
||||
break;
|
||||
if (pr[1].uintVal > pr[2].uintVal)
|
||||
{
|
||||
if (pr[1].uintVal == 0)
|
||||
goto error;
|
||||
pr[1].uintVal -= 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (pr[2].uintVal == 0)
|
||||
goto error;
|
||||
pr[2].uintVal -= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
res->pos_bits = pr[0].uintVal;
|
||||
res->lit_pos_bits = pr[1].uintVal;
|
||||
res->lit_context_bits = pr[2].uintVal;
|
||||
res->dict_size = pr[3].uintVal;
|
||||
//res->num_probs = LzmaGetNumProbs(&s.Properties));
|
||||
//res->num_probs = (LZMA_BASE_SIZE + (LZMA_LIT_SIZE << ((Properties)->lc + (Properties)->lp)))
|
||||
res->num_probs = 1846 + (768 << (res->lit_context_bits + res->lit_pos_bits));
|
||||
|
||||
#ifndef _NO_EXCEPTIONS
|
||||
try {
|
||||
#else
|
||||
# error
|
||||
#endif
|
||||
|
||||
if (enc.SetCoderProperties(propIDs, pr, 7) != S_OK)
|
||||
goto error;
|
||||
if (enc.WriteCoderProperties(&os) != S_OK)
|
||||
goto error;
|
||||
if (os.Overflow) {
|
||||
//r = UPX_E_OUTPUT_OVERRUN;
|
||||
r = UPX_E_NOT_COMPRESSIBLE;
|
||||
goto error;
|
||||
}
|
||||
assert(os.Pos == 5);
|
||||
#if defined(USE_LZMA_PROPERTIES)
|
||||
os.Pos = 1;
|
||||
#else
|
||||
os.Pos = 0;
|
||||
// extra stuff in first byte: 5 high bits convenience for stub decompressor
|
||||
unsigned t = res->lit_context_bits + res->lit_pos_bits;
|
||||
os.WriteByte((t << 3) | res->pos_bits);
|
||||
os.WriteByte((res->lit_pos_bits << 4) | (res->lit_context_bits));
|
||||
#endif
|
||||
|
||||
rh = enc.Code(&is, &os, NULL, NULL, &progress);
|
||||
|
||||
#ifndef _NO_EXCEPTIONS
|
||||
} catch(...) { return UPX_E_OUT_OF_MEMORY; }
|
||||
#endif
|
||||
|
||||
assert(is.Pos <= src_len);
|
||||
assert(os.Pos <= *dst_len);
|
||||
if (rh == E_OUTOFMEMORY)
|
||||
r = UPX_E_OUT_OF_MEMORY;
|
||||
else if (os.Overflow)
|
||||
{
|
||||
assert(os.Pos == *dst_len);
|
||||
//r = UPX_E_OUTPUT_OVERRUN;
|
||||
r = UPX_E_NOT_COMPRESSIBLE;
|
||||
}
|
||||
else if (rh == S_OK)
|
||||
{
|
||||
assert(is.Pos == src_len);
|
||||
r = UPX_E_OK;
|
||||
}
|
||||
|
||||
error:
|
||||
*dst_len = os.Pos;
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
#include "C/Common/Alloc.cpp"
|
||||
#include "C/Common/CRC.cpp"
|
||||
//#include "C/7zip/Common/InBuffer.cpp"
|
||||
#include "C/7zip/Common/OutBuffer.cpp"
|
||||
#include "C/7zip/Common/StreamUtils.cpp"
|
||||
#include "C/7zip/Compress/LZ/LZInWindow.cpp"
|
||||
//#include "C/7zip/Compress/LZ/LZOutWindow.cpp"
|
||||
//#include "C/7zip/Compress/LZMA/LZMADecoder.cpp"
|
||||
#include "C/7zip/Compress/LZMA/LZMAEncoder.cpp"
|
||||
#include "C/7zip/Compress/RangeCoder/RangeCoderBit.cpp"
|
||||
#undef RC_NORMALIZE
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// decompress
|
||||
**************************************************************************/
|
||||
|
||||
#undef _LZMA_IN_CB
|
||||
#undef _LZMA_OUT_READ
|
||||
#undef _LZMA_PROB32
|
||||
#undef _LZMA_LOC_OPT
|
||||
#include "C/7zip/Compress/LZMA_C/LzmaDecode.h"
|
||||
#include "C/7zip/Compress/LZMA_C/LzmaDecode.c"
|
||||
|
||||
int upx_lzma_decompress ( const upx_bytep src, unsigned src_len,
|
||||
upx_bytep dst, unsigned* dst_len,
|
||||
int method,
|
||||
const upx_compress_result_t *cresult )
|
||||
{
|
||||
assert(method == M_LZMA);
|
||||
// see res->num_probs above
|
||||
COMPILE_TIME_ASSERT(sizeof(CProb) == 2)
|
||||
COMPILE_TIME_ASSERT(LZMA_BASE_SIZE == 1846)
|
||||
COMPILE_TIME_ASSERT(LZMA_LIT_SIZE == 768)
|
||||
|
||||
CLzmaDecoderState s; memset(&s, 0, sizeof(s));
|
||||
SizeT src_out = 0, dst_out = 0;
|
||||
int r = UPX_E_ERROR;
|
||||
int rh;
|
||||
|
||||
#if defined(USE_LZMA_PROPERTIES)
|
||||
if (src_len < 2)
|
||||
goto error;
|
||||
rh = LzmaDecodeProperties(&s.Properties, src, src_len);
|
||||
if (rh != 0)
|
||||
goto error;
|
||||
src += 1; src_len -= 1;
|
||||
#else
|
||||
if (src_len < 3)
|
||||
goto error;
|
||||
s.Properties.pb = src[0] & 7;
|
||||
s.Properties.lp = (src[1] >> 4);
|
||||
s.Properties.lc = src[1] & 15;
|
||||
if (s.Properties.pb >= 5) goto error;
|
||||
if (s.Properties.lp >= 5) goto error;
|
||||
if (s.Properties.lc >= 9) goto error;
|
||||
// extra
|
||||
if ((src[0] >> 3) != s.Properties.lc + s.Properties.lp) goto error;
|
||||
src += 2; src_len -= 2;
|
||||
#endif
|
||||
|
||||
if (cresult)
|
||||
{
|
||||
assert(cresult->method == method);
|
||||
assert(cresult->result_lzma.pos_bits == (unsigned) s.Properties.pb);
|
||||
assert(cresult->result_lzma.lit_pos_bits == (unsigned) s.Properties.lp);
|
||||
assert(cresult->result_lzma.lit_context_bits == (unsigned) s.Properties.lc);
|
||||
assert(cresult->result_lzma.num_probs == (unsigned) LzmaGetNumProbs(&s.Properties));
|
||||
}
|
||||
s.Probs = (CProb *) malloc(sizeof(CProb) * LzmaGetNumProbs(&s.Properties));
|
||||
if (!s.Probs)
|
||||
{
|
||||
r = UPX_E_OUT_OF_MEMORY;
|
||||
goto error;
|
||||
}
|
||||
rh = LzmaDecode(&s, src, src_len, &src_out, dst, *dst_len, &dst_out);
|
||||
assert(src_out <= src_len);
|
||||
assert(dst_out <= *dst_len);
|
||||
if (rh == 0)
|
||||
{
|
||||
r = UPX_E_OK;
|
||||
if (src_out != src_len)
|
||||
r = UPX_E_INPUT_NOT_CONSUMED;
|
||||
}
|
||||
|
||||
error:
|
||||
*dst_len = dst_out;
|
||||
free(s.Probs);
|
||||
|
||||
UNUSED(cresult);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// test_overlap
|
||||
**************************************************************************/
|
||||
|
||||
int upx_lzma_test_overlap ( const upx_bytep buf, unsigned src_off,
|
||||
unsigned src_len, unsigned* dst_len,
|
||||
int method,
|
||||
const upx_compress_result_t *cresult )
|
||||
{
|
||||
assert(method == M_LZMA);
|
||||
|
||||
// FIXME - implement this
|
||||
// Note that Packer::verifyOverlappingDecompression() will
|
||||
// verify the final result in any case.
|
||||
UNUSED(buf);
|
||||
|
||||
unsigned overlap_overhead = src_off + src_len - *dst_len;
|
||||
//printf("upx_lzma_test_overlap: %d\n", overlap_overhead);
|
||||
if ((int)overlap_overhead >= 256)
|
||||
return UPX_E_OK;
|
||||
|
||||
UNUSED(cresult);
|
||||
return UPX_E_ERROR;
|
||||
}
|
||||
|
||||
|
||||
#endif /* WITH_LZMA */
|
||||
/*
|
||||
vi:ts=4:et:nowrap
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,275 @@
|
||||
/* compress_ucl.cpp --
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
and/or modify them under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING.
|
||||
If not, write to the Free Software Foundation, Inc.,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
||||
*/
|
||||
|
||||
|
||||
#include "conf.h"
|
||||
#include "compress.h"
|
||||
#if !defined(WITH_UCL)
|
||||
extern int compress_ucl_dummy;
|
||||
int compress_ucl_dummy = 0;
|
||||
#else
|
||||
|
||||
#if 1 && !defined(UCL_USE_ASM) && (ACC_ARCH_I386)
|
||||
# if (ACC_CC_GNUC || ACC_CC_INTELC || ACC_CC_MSC || ACC_CC_WATCOMC)
|
||||
# define UCL_USE_ASM
|
||||
# endif
|
||||
#endif
|
||||
#if defined(UCL_NO_ASM)
|
||||
# undef UCL_USE_ASM
|
||||
#endif
|
||||
#if defined(ACC_CFG_NO_UNALIGNED)
|
||||
# undef UCL_USE_ASM
|
||||
#endif
|
||||
#if 1 && defined(UCL_USE_ASM)
|
||||
# include <ucl/ucl_asm.h>
|
||||
# define ucl_nrv2b_decompress_safe_8 ucl_nrv2b_decompress_asm_safe_8
|
||||
# define ucl_nrv2b_decompress_safe_le16 ucl_nrv2b_decompress_asm_safe_le16
|
||||
# define ucl_nrv2b_decompress_safe_le32 ucl_nrv2b_decompress_asm_safe_le32
|
||||
# define ucl_nrv2d_decompress_safe_8 ucl_nrv2d_decompress_asm_safe_8
|
||||
# define ucl_nrv2d_decompress_safe_le16 ucl_nrv2d_decompress_asm_safe_le16
|
||||
# define ucl_nrv2d_decompress_safe_le32 ucl_nrv2d_decompress_asm_safe_le32
|
||||
# define ucl_nrv2e_decompress_safe_8 ucl_nrv2e_decompress_asm_safe_8
|
||||
# define ucl_nrv2e_decompress_safe_le16 ucl_nrv2e_decompress_asm_safe_le16
|
||||
# define ucl_nrv2e_decompress_safe_le32 ucl_nrv2e_decompress_asm_safe_le32
|
||||
#endif
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
static int convert_errno_from_ucl(int r)
|
||||
{
|
||||
switch (r)
|
||||
{
|
||||
case UCL_E_OK: return UPX_E_OK;
|
||||
case UCL_E_ERROR: return UPX_E_ERROR;
|
||||
case UCL_E_OUT_OF_MEMORY: return UPX_E_OUT_OF_MEMORY;
|
||||
case UCL_E_NOT_COMPRESSIBLE: return UPX_E_NOT_COMPRESSIBLE;
|
||||
case UCL_E_INPUT_OVERRUN: return UPX_E_INPUT_OVERRUN;
|
||||
case UCL_E_OUTPUT_OVERRUN: return UPX_E_OUTPUT_OVERRUN;
|
||||
case UCL_E_LOOKBEHIND_OVERRUN: return UPX_E_LOOKBEHIND_OVERRUN;
|
||||
case UCL_E_EOF_NOT_FOUND: return UPX_E_EOF_NOT_FOUND;
|
||||
case UCL_E_INPUT_NOT_CONSUMED: return UPX_E_INPUT_NOT_CONSUMED;
|
||||
// case UCL_E_NOT_YET_IMPLEMENTED: return UPX_E_NOT_YET_IMPLEMENTED;
|
||||
case UCL_E_INVALID_ARGUMENT: return UPX_E_INVALID_ARGUMENT;
|
||||
// UCL extra:
|
||||
case UCL_E_OVERLAP_OVERRUN: return UPX_E_ERROR;
|
||||
}
|
||||
return UPX_E_ERROR;
|
||||
}
|
||||
|
||||
|
||||
static void wrap_nprogress_ucl(ucl_uint a, ucl_uint b, int state, ucl_voidp user)
|
||||
{
|
||||
if (state != -1 && state != 3) return;
|
||||
upx_callback_p cb = (upx_callback_p) user;
|
||||
if (cb && cb->nprogress)
|
||||
cb->nprogress(cb, a, b);
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
int upx_ucl_compress ( const upx_bytep src, unsigned src_len,
|
||||
upx_bytep dst, unsigned* dst_len,
|
||||
upx_callback_p cb_parm,
|
||||
int method, int level,
|
||||
const upx_compress_config_t *cconf_parm,
|
||||
upx_compress_result_t *cresult )
|
||||
{
|
||||
int r;
|
||||
assert(level > 0); assert(cresult != NULL);
|
||||
|
||||
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;
|
||||
memset(&cconf, 0xff, sizeof(cconf));
|
||||
if (cconf_parm)
|
||||
cconf = cconf_parm->conf_ucl; // struct copy
|
||||
|
||||
ucl_uint *res = cresult->result_ucl.result;
|
||||
// assume no info available - fill in worst case results
|
||||
//res[0] = 1; // min_offset_found - NOT USED
|
||||
res[1] = src_len - 1; // max_offset_found
|
||||
//res[2] = 2; // min_match_found - NOT USED
|
||||
res[3] = src_len - 1; // max_match_found
|
||||
//res[4] = 1; // min_run_found - NOT USED
|
||||
res[5] = src_len; // max_run_found
|
||||
res[6] = 1; // first_offset_found
|
||||
//res[7] = 999999; // same_match_offsets_found - NOT USED
|
||||
|
||||
// prepare bit-buffer settings
|
||||
cconf.bb_endian = 0;
|
||||
cconf.bb_size = 0;
|
||||
if (method >= M_NRV2B_LE32 && method <= M_CL1B_LE16)
|
||||
{
|
||||
static const unsigned char sizes[3] = {32, 8, 16};
|
||||
cconf.bb_size = sizes[(method - M_NRV2B_LE32) % 3];
|
||||
}
|
||||
else {
|
||||
throwInternalError("unknown compression method");
|
||||
return UPX_E_ERROR;
|
||||
}
|
||||
|
||||
// optimize compression parms
|
||||
if (level <= 3 && cconf.max_offset == UCL_UINT_MAX)
|
||||
cconf.max_offset = 8*1024-1;
|
||||
else if (level == 4 && cconf.max_offset == UCL_UINT_MAX)
|
||||
cconf.max_offset = 32*1024-1;
|
||||
|
||||
if M_IS_NRV2B(method)
|
||||
r = ucl_nrv2b_99_compress(src, src_len, dst, dst_len,
|
||||
&cb, level, &cconf, res);
|
||||
else if M_IS_NRV2D(method)
|
||||
r = ucl_nrv2d_99_compress(src, src_len, dst, dst_len,
|
||||
&cb, level, &cconf, res);
|
||||
else if M_IS_NRV2E(method)
|
||||
r = ucl_nrv2e_99_compress(src, src_len, dst, dst_len,
|
||||
&cb, level, &cconf, res);
|
||||
else {
|
||||
throwInternalError("unknown compression method");
|
||||
return UPX_E_ERROR;
|
||||
}
|
||||
|
||||
return convert_errno_from_ucl(r);
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
int upx_ucl_decompress ( const upx_bytep src, unsigned src_len,
|
||||
upx_bytep dst, unsigned* dst_len,
|
||||
int method,
|
||||
const upx_compress_result_t *cresult )
|
||||
{
|
||||
int r;
|
||||
|
||||
switch (method)
|
||||
{
|
||||
case M_NRV2B_8:
|
||||
r = ucl_nrv2b_decompress_safe_8(src,src_len,dst,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2B_LE16:
|
||||
r = ucl_nrv2b_decompress_safe_le16(src,src_len,dst,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2B_LE32:
|
||||
r = ucl_nrv2b_decompress_safe_le32(src,src_len,dst,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2D_8:
|
||||
r = ucl_nrv2d_decompress_safe_8(src,src_len,dst,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2D_LE16:
|
||||
r = ucl_nrv2d_decompress_safe_le16(src,src_len,dst,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2D_LE32:
|
||||
r = ucl_nrv2d_decompress_safe_le32(src,src_len,dst,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2E_8:
|
||||
r = ucl_nrv2e_decompress_safe_8(src,src_len,dst,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2E_LE16:
|
||||
r = ucl_nrv2e_decompress_safe_le16(src,src_len,dst,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2E_LE32:
|
||||
r = ucl_nrv2e_decompress_safe_le32(src,src_len,dst,dst_len,NULL);
|
||||
break;
|
||||
default:
|
||||
throwInternalError("unknown decompression method");
|
||||
return UPX_E_ERROR;
|
||||
}
|
||||
|
||||
UNUSED(cresult);
|
||||
return convert_errno_from_ucl(r);
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
int upx_ucl_test_overlap ( const upx_bytep buf, unsigned src_off,
|
||||
unsigned src_len, unsigned* dst_len,
|
||||
int method,
|
||||
const upx_compress_result_t *cresult )
|
||||
{
|
||||
int r;
|
||||
|
||||
switch (method)
|
||||
{
|
||||
case M_NRV2B_8:
|
||||
r = ucl_nrv2b_test_overlap_8(buf,src_off,src_len,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2B_LE16:
|
||||
r = ucl_nrv2b_test_overlap_le16(buf,src_off,src_len,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2B_LE32:
|
||||
r = ucl_nrv2b_test_overlap_le32(buf,src_off,src_len,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2D_8:
|
||||
r = ucl_nrv2d_test_overlap_8(buf,src_off,src_len,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2D_LE16:
|
||||
r = ucl_nrv2d_test_overlap_le16(buf,src_off,src_len,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2D_LE32:
|
||||
r = ucl_nrv2d_test_overlap_le32(buf,src_off,src_len,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2E_8:
|
||||
r = ucl_nrv2e_test_overlap_8(buf,src_off,src_len,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2E_LE16:
|
||||
r = ucl_nrv2e_test_overlap_le16(buf,src_off,src_len,dst_len,NULL);
|
||||
break;
|
||||
case M_NRV2E_LE32:
|
||||
r = ucl_nrv2e_test_overlap_le32(buf,src_off,src_len,dst_len,NULL);
|
||||
break;
|
||||
default:
|
||||
throwInternalError("unknown decompression method");
|
||||
return UPX_E_ERROR;
|
||||
}
|
||||
|
||||
UNUSED(cresult);
|
||||
return convert_errno_from_ucl(r);
|
||||
}
|
||||
|
||||
|
||||
#endif /* WITH_UCL */
|
||||
/*
|
||||
vi:ts=4:et:nowrap
|
||||
*/
|
||||
|
||||
+159
-47
@@ -2,8 +2,8 @@
|
||||
|
||||
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) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -144,35 +144,27 @@
|
||||
# undef __unix
|
||||
#endif
|
||||
|
||||
|
||||
#if !defined(WITH_UCL)
|
||||
# error "please set UCLDIR in the Makefile"
|
||||
# define WITH_UCL 1
|
||||
#endif
|
||||
#if defined(WITH_UCL)
|
||||
# include <ucl/uclconf.h>
|
||||
# include <ucl/ucl.h>
|
||||
# if !defined(UCL_VERSION) || (UCL_VERSION < 0x010200L)
|
||||
# error "please upgrade your UCL installation"
|
||||
# endif
|
||||
# if !defined(UPX_UINT_MAX)
|
||||
# define UPX_UINT_MAX UCL_UINT_MAX
|
||||
# define upx_uint ucl_uint
|
||||
# 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
|
||||
#if 0 && !defined(WITH_LZMA)
|
||||
# define WITH_LZMA 1
|
||||
#endif
|
||||
#if defined(UPX_OFFICIAL_BUILD)
|
||||
# if !defined(WITH_LZMA) || !defined(WITH_NRV) || !defined(WITH_UCL)
|
||||
# error
|
||||
# endif
|
||||
#endif
|
||||
#if defined(WITH_NRV)
|
||||
# include <nrv/nrvconf.h>
|
||||
#endif
|
||||
#if defined(WITH_UCL)
|
||||
# include <ucl/uclconf.h>
|
||||
# include <ucl/ucl.h>
|
||||
# if !defined(UCL_VERSION) || (UCL_VERSION < 0x010300L)
|
||||
# error "please upgrade your UCL installation"
|
||||
# endif
|
||||
#endif
|
||||
#if !defined(__UPX_CHECKER)
|
||||
# if defined(__UCL_CHECKER) || defined(__NRV_CHECKER)
|
||||
# define __UPX_CHECKER
|
||||
@@ -182,6 +174,94 @@
|
||||
# error "UINT_MAX"
|
||||
#endif
|
||||
|
||||
#define upx_byte unsigned char
|
||||
#define upx_bytep upx_byte *
|
||||
#define UPX_E_OK (0)
|
||||
#define UPX_E_ERROR (-1)
|
||||
#define UPX_E_OUT_OF_MEMORY (-2)
|
||||
#define UPX_E_NOT_COMPRESSIBLE (-3)
|
||||
#define UPX_E_INPUT_OVERRUN (-4)
|
||||
#define UPX_E_OUTPUT_OVERRUN (-5)
|
||||
#define UPX_E_LOOKBEHIND_OVERRUN (-6)
|
||||
#define UPX_E_EOF_NOT_FOUND (-7)
|
||||
#define UPX_E_INPUT_NOT_CONSUMED (-8)
|
||||
#define UPX_E_NOT_YET_IMPLEMENTED (-9)
|
||||
#define UPX_E_INVALID_ARGUMENT (-10)
|
||||
|
||||
struct upx_callback_t;
|
||||
#define upx_callback_p upx_callback_t *
|
||||
typedef void* (__acc_cdecl *upx_alloc_func_t)
|
||||
(upx_callback_p self, unsigned items, unsigned size);
|
||||
typedef void (__acc_cdecl *upx_free_func_t)
|
||||
(upx_callback_p self, void* ptr);
|
||||
typedef void (__acc_cdecl *upx_progress_func_t)
|
||||
(upx_callback_p, unsigned, unsigned);
|
||||
|
||||
struct upx_callback_t
|
||||
{
|
||||
#if 0
|
||||
upx_alloc_func_t nalloc;
|
||||
upx_free_func_t nfree;
|
||||
#endif
|
||||
upx_progress_func_t nprogress;
|
||||
void * user1;
|
||||
#if 0
|
||||
unsigned user2;
|
||||
unsigned user3;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
struct lzma_compress_config_t
|
||||
{
|
||||
unsigned max_num_probs;
|
||||
#if 0
|
||||
unsigned pos_bits; // pb
|
||||
unsigned lit_pos_bits; // lp
|
||||
unsigned lit_context_bits; // lc
|
||||
unsigned dict_size;
|
||||
unsigned mf_passes;
|
||||
#endif
|
||||
void reset() { memset(this, 0, sizeof(*this)); }
|
||||
};
|
||||
|
||||
#define upx_compress_config_p upx_compress_config_t *
|
||||
struct upx_compress_config_t
|
||||
{
|
||||
lzma_compress_config_t conf_lzma;
|
||||
ucl_compress_config_t conf_ucl;
|
||||
void reset() {
|
||||
conf_lzma.reset();
|
||||
memset(&conf_ucl, 0xff, sizeof(conf_ucl));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct lzma_compress_result_t
|
||||
{
|
||||
unsigned pos_bits; // pb
|
||||
unsigned lit_pos_bits; // lp
|
||||
unsigned lit_context_bits; // lc
|
||||
unsigned dict_size;
|
||||
unsigned num_probs;
|
||||
};
|
||||
|
||||
struct ucl_compress_result_t
|
||||
{
|
||||
ucl_uint result[16];
|
||||
};
|
||||
|
||||
struct upx_compress_result_t
|
||||
{
|
||||
#if 1
|
||||
// debug
|
||||
int method, level;
|
||||
unsigned u_len, c_len;
|
||||
#endif
|
||||
lzma_compress_result_t result_lzma;
|
||||
ucl_compress_result_t result_ucl;
|
||||
};
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// system includes
|
||||
@@ -292,13 +372,16 @@
|
||||
#define index upx_index
|
||||
#define outp upx_outp
|
||||
|
||||
#undef PAGE_MASK
|
||||
#undef PAGE_SIZE
|
||||
|
||||
|
||||
#undef __attribute_packed
|
||||
#if (ACC_CC_GNUC || ACC_CC_INTELC || ACC_CC_PATHSCALE)
|
||||
# if (1 && (ACC_ARCH_IA32))
|
||||
# if (1 && (ACC_ARCH_I386))
|
||||
# define __attribute_packed
|
||||
# else
|
||||
# define __attribute_packed __attribute__((__packed__,__aligned__(1)))
|
||||
# define __attribute_packed __attribute__((__packed__,__aligned__(1)))
|
||||
# endif
|
||||
#else
|
||||
# define __attribute_packed
|
||||
@@ -333,10 +416,10 @@
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(acc_alignof)
|
||||
#if defined(__acc_alignof)
|
||||
# define COMPILE_TIME_ASSERT_ALIGNOF(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
|
||||
# define COMPILE_TIME_ASSERT_ALIGNOF(a,b) \
|
||||
__COMPILE_TIME_ASSERT_ALIGNOF_SIZEOF(a,b)
|
||||
@@ -414,6 +497,8 @@ inline void operator delete[](void *p)
|
||||
|
||||
|
||||
// compression methods - DO NOT CHANGE
|
||||
#define M_SKIP (-2)
|
||||
#define M_END (-1)
|
||||
#define M_NRV2B_LE32 2
|
||||
#define M_NRV2B_8 3
|
||||
#define M_NRV2B_LE16 4
|
||||
@@ -423,10 +508,16 @@ inline void operator delete[](void *p)
|
||||
#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_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) == M_LZMA)
|
||||
|
||||
|
||||
// Executable formats. Note: big endian types are >= 128.
|
||||
@@ -449,8 +540,22 @@ inline void operator delete[](void *p)
|
||||
#define UPX_F_ELKS_8086 17
|
||||
#define UPX_F_PS1_EXE 18
|
||||
#define UPX_F_VMLINUX_i386 19
|
||||
#define UPX_F_LINUX_ELFI_i386 20
|
||||
#define UPX_F_WINCE_ARM_PE 21
|
||||
#define UPX_F_LINUX_ELF64_AMD 22
|
||||
#define UPX_F_LINUX_ELF32_ARMLE 23
|
||||
|
||||
#define UPX_F_BSD_i386 24
|
||||
#define UPX_F_BSD_ELF_i386 25
|
||||
#define UPX_F_BSD_SH_i386 26
|
||||
|
||||
#define UPX_F_PLAIN_TEXT 127
|
||||
|
||||
#define UPX_F_ATARI_TOS 129
|
||||
#define UPX_F_SOLARIS_SPARC 130
|
||||
#define UPX_F_MACH_PPC32 131
|
||||
#define UPX_F_LINUX_ELFPPC32 132
|
||||
#define UPX_F_LINUX_ELF32_ARMBE 133
|
||||
|
||||
|
||||
#define UPX_MAGIC_LE32 0x21585055 /* "UPX!" */
|
||||
@@ -473,11 +578,16 @@ inline void operator delete[](void *p)
|
||||
#include "console.h"
|
||||
|
||||
|
||||
// classes
|
||||
class ElfLinker;
|
||||
typedef ElfLinker Linker;
|
||||
|
||||
|
||||
// main.cpp
|
||||
extern const char *progname;
|
||||
void init_options(struct options_t *o);
|
||||
bool set_ec(int ec);
|
||||
#if defined(__GNUC__)
|
||||
#if (ACC_CC_GNUC || ACC_CC_LLVM || ACC_CC_PATHSCALE)
|
||||
void e_exit(int ec) __attribute__((__noreturn__));
|
||||
#else
|
||||
void e_exit(int ec);
|
||||
@@ -489,23 +599,23 @@ void printSetNl(int need_nl);
|
||||
void printClearLine(FILE *f = NULL);
|
||||
void printErr(const char *iname, const Throwable *e);
|
||||
void printUnhandledException(const char *iname, const std::exception *e);
|
||||
#if defined(__GNUC__)
|
||||
#if (ACC_CC_GNUC || ACC_CC_LLVM || ACC_CC_PATHSCALE)
|
||||
void __acc_cdecl_va printErr(const char *iname, const char *format, ...)
|
||||
__attribute__((__format__(printf,2,3)));
|
||||
__attribute__((__format__(__printf__,2,3)));
|
||||
void __acc_cdecl_va printWarn(const char *iname, const char *format, ...)
|
||||
__attribute__((__format__(printf,2,3)));
|
||||
__attribute__((__format__(__printf__,2,3)));
|
||||
#else
|
||||
void __acc_cdecl_va printErr(const char *iname, const char *format, ...);
|
||||
void __acc_cdecl_va printWarn(const char *iname, const char *format, ...);
|
||||
#endif
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#if (ACC_CC_GNUC || ACC_CC_LLVM || ACC_CC_PATHSCALE)
|
||||
void __acc_cdecl_va infoWarning(const char *format, ...)
|
||||
__attribute__((__format__(printf,1,2)));
|
||||
__attribute__((__format__(__printf__,1,2)));
|
||||
void __acc_cdecl_va infoHeader(const char *format, ...)
|
||||
__attribute__((__format__(printf,1,2)));
|
||||
__attribute__((__format__(__printf__,1,2)));
|
||||
void __acc_cdecl_va info(const char *format, ...)
|
||||
__attribute__((__format__(printf,1,2)));
|
||||
__attribute__((__format__(__printf__,1,2)));
|
||||
#else
|
||||
void __acc_cdecl_va infoWarning(const char *format, ...);
|
||||
void __acc_cdecl_va infoHeader(const char *format, ...);
|
||||
@@ -532,18 +642,20 @@ void show_version(int);
|
||||
unsigned upx_adler32(const void *buf, unsigned len, unsigned adler=1);
|
||||
unsigned upx_crc32(const void *buf, unsigned len, unsigned crc=0);
|
||||
|
||||
int upx_compress ( const upx_bytep src, upx_uint src_len,
|
||||
upx_bytep dst, upx_uintp dst_len,
|
||||
upx_progress_callback_t *cb,
|
||||
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 struct upx_compress_config_t *conf,
|
||||
upx_uintp result );
|
||||
int upx_decompress ( const upx_bytep src, upx_uint src_len,
|
||||
upx_bytep dst, upx_uintp dst_len,
|
||||
int method );
|
||||
int upx_test_overlap ( const upx_bytep buf, upx_uint src_off,
|
||||
upx_uint src_len, upx_uintp dst_len,
|
||||
int method );
|
||||
const upx_compress_config_t *cconf,
|
||||
upx_compress_result_t *cresult );
|
||||
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 upx_test_overlap ( const upx_bytep buf, unsigned src_off,
|
||||
unsigned src_len, unsigned* dst_len,
|
||||
int method,
|
||||
const upx_compress_result_t *cresult );
|
||||
|
||||
|
||||
#endif /* __cplusplus */
|
||||
|
||||
+3
-3
@@ -2,8 +2,8 @@
|
||||
|
||||
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) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -117,7 +117,7 @@ typedef struct
|
||||
int (*init)(FILE *f, int, int);
|
||||
int (*set_fg)(FILE *f, int fg);
|
||||
void (*print0)(FILE *f, const char *s);
|
||||
upx_bool (*intro)(FILE *f);
|
||||
bool (*intro)(FILE *f);
|
||||
}
|
||||
console_t;
|
||||
|
||||
|
||||
+2
-2
@@ -2,8 +2,8 @@
|
||||
|
||||
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) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
|
||||
+2
-2
@@ -2,8 +2,8 @@
|
||||
|
||||
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) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
|
||||
+4
-2
@@ -2,8 +2,8 @@
|
||||
|
||||
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) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -40,6 +40,8 @@ void File::chmod(const char *name, int mode)
|
||||
#if defined(HAVE_CHMOD)
|
||||
if (::chmod(name,mode) != 0)
|
||||
throwIOException(name,errno);
|
||||
#else
|
||||
UNUSED(name); UNUSED(mode);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
+2
-4
@@ -2,8 +2,8 @@
|
||||
|
||||
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) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -131,7 +131,6 @@ public:
|
||||
|
||||
off_t getBytesWritten() const { return bytes_written; }
|
||||
|
||||
#if (UPX_VERSION_HEX >= 0x019000)
|
||||
// FIXME - these won't work when using the `--stdout' option
|
||||
virtual void seek(off_t off, int whence)
|
||||
{
|
||||
@@ -144,7 +143,6 @@ public:
|
||||
write(buf, len);
|
||||
bytes_written -= len; // restore
|
||||
}
|
||||
#endif
|
||||
|
||||
// util
|
||||
static void dump(const char *name, const void *buf, int len, int flags=-1);
|
||||
|
||||
+2
-2
@@ -2,8 +2,8 @@
|
||||
|
||||
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) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
|
||||
+3
-3
@@ -2,8 +2,8 @@
|
||||
|
||||
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) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -22,7 +22,7 @@
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
markus@oberhumer.com ml1050@cdata.tvnet.hu
|
||||
markus@oberhumer.com ml1050@users.sourceforge.net
|
||||
*/
|
||||
|
||||
|
||||
|
||||
+77
-2
@@ -2,8 +2,8 @@
|
||||
|
||||
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) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -383,6 +383,81 @@ static int s_ct32_e8e9_bswap_be(Filter *f)
|
||||
|
||||
#undef CT32
|
||||
|
||||
/*************************************************************************
|
||||
// 24-bit ARM calltrick ("naive")
|
||||
**************************************************************************/
|
||||
|
||||
#define CT24ARM_LE(f, cond, addvalue, get, set) \
|
||||
upx_byte *b = f->buf; \
|
||||
upx_byte *b_end = b + f->buf_len - 4; \
|
||||
do { \
|
||||
if (cond) \
|
||||
{ \
|
||||
unsigned a = (unsigned) (b - f->buf); \
|
||||
f->lastcall = a; \
|
||||
set(b, get(b) + (addvalue)); \
|
||||
f->calls++; \
|
||||
} \
|
||||
b += 4; \
|
||||
} while (b < b_end); \
|
||||
if (f->lastcall) f->lastcall += 4; \
|
||||
return 0;
|
||||
|
||||
|
||||
#define ARMCT_COND_le (((b[3] & 0x0f) == 0x0b))
|
||||
|
||||
static int f_ct24arm_le(Filter *f)
|
||||
{
|
||||
CT24ARM_LE(f, ARMCT_COND_le, a / 4 + f->addvalue, get_le24, set_le24)
|
||||
}
|
||||
|
||||
static int u_ct24arm_le(Filter *f)
|
||||
{
|
||||
CT24ARM_LE(f, ARMCT_COND_le, 0 - a / 4 - f->addvalue, get_le24, set_le24)
|
||||
}
|
||||
|
||||
static int s_ct24arm_le(Filter *f)
|
||||
{
|
||||
CT24ARM_LE(f, ARMCT_COND_le, a + f->addvalue, get_le24, set_dummy)
|
||||
}
|
||||
|
||||
#undef CT24ARM_LE
|
||||
|
||||
#define CT24ARM_BE(f, cond, addvalue, get, set) \
|
||||
upx_byte *b = f->buf; \
|
||||
upx_byte *b_end = b + f->buf_len - 4; \
|
||||
do { \
|
||||
if (cond) \
|
||||
{ \
|
||||
unsigned a = (unsigned) (b - f->buf); \
|
||||
f->lastcall = a; \
|
||||
set(1+b, get(1+b) + (addvalue)); \
|
||||
f->calls++; \
|
||||
} \
|
||||
b += 4; \
|
||||
} while (b < b_end); \
|
||||
if (f->lastcall) f->lastcall += 4; \
|
||||
return 0;
|
||||
|
||||
#define ARMCT_COND_be (((b[0] & 0x0f) == 0x0b))
|
||||
|
||||
static int f_ct24arm_be(Filter *f)
|
||||
{
|
||||
CT24ARM_BE(f, ARMCT_COND_be, a / 4 + f->addvalue, get_be24, set_be24)
|
||||
}
|
||||
|
||||
static int u_ct24arm_be(Filter *f)
|
||||
{
|
||||
CT24ARM_BE(f, ARMCT_COND_be, 0 - a / 4 - f->addvalue, get_be24, set_be24)
|
||||
}
|
||||
|
||||
static int s_ct24arm_be(Filter *f)
|
||||
{
|
||||
CT24ARM_BE(f, ARMCT_COND_be, a + f->addvalue, get_be24, set_dummy)
|
||||
}
|
||||
|
||||
#undef CT24ARM_BE
|
||||
#undef ARMCT_COND
|
||||
|
||||
/*
|
||||
vi:ts=4:et:nowrap
|
||||
|
||||
+2
-2
@@ -2,8 +2,8 @@
|
||||
|
||||
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) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
|
||||
+3
-3
@@ -2,9 +2,9 @@
|
||||
|
||||
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
|
||||
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
|
||||
|
||||
+3
-3
@@ -2,9 +2,9 @@
|
||||
|
||||
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
|
||||
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
|
||||
|
||||
+3
-3
@@ -2,9 +2,9 @@
|
||||
|
||||
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
|
||||
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
|
||||
|
||||
+2
-2
@@ -2,8 +2,8 @@
|
||||
|
||||
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) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
|
||||
+2
-2
@@ -2,8 +2,8 @@
|
||||
|
||||
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) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
|
||||
@@ -0,0 +1,155 @@
|
||||
/* ppcbxx.h -- PowerPC Branch trick
|
||||
|
||||
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) 2004-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>
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// filter / scan
|
||||
**************************************************************************/
|
||||
|
||||
#define W_CTO 4 /* width of cto; must match stub/ppc_bxx.S */
|
||||
|
||||
static int F(Filter *f)
|
||||
{
|
||||
#ifdef U
|
||||
// filter
|
||||
upx_byte *b = f->buf;
|
||||
const unsigned addvalue = f->addvalue;
|
||||
#else
|
||||
// scan
|
||||
const upx_byte *b = f->buf;
|
||||
#endif
|
||||
const unsigned size = umin(f->buf_len, -(~0u<<(32 - (6+ W_CTO))));
|
||||
const unsigned size4 = size -4;
|
||||
|
||||
unsigned ic;
|
||||
unsigned calls = 0, noncalls = 0;
|
||||
unsigned lastnoncall = size, lastcall = 0;
|
||||
|
||||
// find 26-2-W_CTO bits of displacements that contain no targets
|
||||
{
|
||||
unsigned char buf[256];
|
||||
unsigned short wbuf[256];
|
||||
const size_t WW = (size_t)0 - (~(size_t)0) << W_CTO; // ???
|
||||
memset(wbuf, 0, sizeof(wbuf));
|
||||
memset(buf , 0, WW);
|
||||
memset(buf + WW, 1, 256 - WW);
|
||||
|
||||
for (ic = 0; ic<=size4; ic+=4) if (COND(b,ic)) {
|
||||
unsigned const off = (int)(get_be32(b+ic)<<6) >>6;
|
||||
if (size <= (off & (~0u<<2))+ic) {
|
||||
buf[(~(~0u<<W_CTO)) & (off>>(26 - W_CTO))] |= 1;
|
||||
++wbuf[0xff&(off>>18)];
|
||||
}
|
||||
}
|
||||
|
||||
if (getcto(f, buf) < 0) {
|
||||
if (0!=W_CTO) // FIXME: what is this ???
|
||||
return -1;
|
||||
f->cto = 0;
|
||||
}
|
||||
}
|
||||
const unsigned char cto8 = f->cto;
|
||||
#ifdef U
|
||||
const unsigned cto = (unsigned)f->cto << (24+2 - W_CTO);
|
||||
#endif
|
||||
|
||||
for (ic = 0; ic<=size4; ic+=4) if (COND(b,ic)) {
|
||||
unsigned const word = get_be32(b+ic);
|
||||
unsigned const off = (int)(word<<6) >>6;
|
||||
unsigned const jc = (off & (~0u<<2))+ic;
|
||||
// try to detect 'real' calls only
|
||||
if (jc < size) {
|
||||
#ifdef U
|
||||
set_be32(b+ic,(0xfc000003&word) | (jc+addvalue+cto));
|
||||
#endif
|
||||
calls++;
|
||||
lastcall = ic;
|
||||
}
|
||||
else {
|
||||
assert(0==W_CTO // FIXME: what is this ???
|
||||
|| (~(~0u<<W_CTO) & (word>>(24+2 - W_CTO))) != cto8); // this should not happen
|
||||
lastnoncall = ic;
|
||||
noncalls++;
|
||||
}
|
||||
}
|
||||
|
||||
f->calls = calls;
|
||||
f->noncalls = noncalls;
|
||||
f->lastcall = lastcall;
|
||||
|
||||
#if 0
|
||||
printf("\ncalls=%d noncalls=%d text_size=%x calltrickoffset=%x\n",
|
||||
calls,noncalls,size,cto8);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// unfilter
|
||||
**************************************************************************/
|
||||
|
||||
#ifdef U
|
||||
static int U(Filter *f)
|
||||
{
|
||||
upx_byte *b = f->buf;
|
||||
const unsigned size4 = umin(f->buf_len - 4, -(~0u<<(32 - (6+ W_CTO))));
|
||||
const unsigned addvalue = f->addvalue;
|
||||
|
||||
unsigned ic;
|
||||
|
||||
for (ic = 0; ic<=size4; ic+=4) if (COND(b,ic)) {
|
||||
unsigned const word = get_be32(b+ic);
|
||||
if ((~(~0u<<W_CTO) & (word>>(24+2 - W_CTO))) == f->cto) {
|
||||
unsigned const jc = word & (~(~0u<<(26 - W_CTO)) & (~0u<<2));
|
||||
set_be32(b+ic, (0xfc000003&word)|(0x03fffffc&(jc-ic-addvalue)));
|
||||
f->calls++;
|
||||
f->lastcall = ic;
|
||||
}
|
||||
else {
|
||||
f->noncalls++;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#undef F
|
||||
#undef U
|
||||
|
||||
#undef W_CTO
|
||||
|
||||
/*
|
||||
vi:ts=4:et:nowrap
|
||||
*/
|
||||
|
||||
+2
-2
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2004 Laszlo Molnar
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
|
||||
+2
-2
@@ -2,8 +2,8 @@
|
||||
|
||||
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) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
|
||||
+2
-2
@@ -2,8 +2,8 @@
|
||||
|
||||
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) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
|
||||
+2
-2
@@ -2,8 +2,8 @@
|
||||
|
||||
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) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
|
||||
+2
-2
@@ -2,8 +2,8 @@
|
||||
|
||||
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) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
|
||||
+29
-3
@@ -2,8 +2,8 @@
|
||||
|
||||
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) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -22,13 +22,19 @@
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
markus@oberhumer.com ml1050@cdata.tvnet.hu
|
||||
markus@oberhumer.com ml1050@users.sourceforge.net
|
||||
*/
|
||||
|
||||
|
||||
#include "conf.h"
|
||||
#include "filter.h"
|
||||
|
||||
static unsigned
|
||||
umin(unsigned const a, unsigned const b)
|
||||
{
|
||||
return (a<=b) ? a : b;
|
||||
}
|
||||
|
||||
|
||||
#define set_dummy(p, v) ((void)0)
|
||||
#define get_8(p) (*(p))
|
||||
@@ -145,6 +151,19 @@
|
||||
#undef COND_CALL
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// PowerPC branch [incl. call] trick
|
||||
**************************************************************************/
|
||||
|
||||
#define COND(b,x) (18==(get_be32(b+x)>>26))
|
||||
#define F f_ppcbxx
|
||||
#define U u_ppcbxx
|
||||
#include "filter/ppcbxx.h"
|
||||
#define F s_ppcbxx
|
||||
#include "filter/ppcbxx.h"
|
||||
#undef COND
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// database for use in class Filter
|
||||
**************************************************************************/
|
||||
@@ -205,6 +224,10 @@ const FilterImp::FilterEntry FilterImp::filters[] = {
|
||||
{ 0x46, 6, 0x00ffffff, f_ctok32_e8e9_bswap_le, u_ctok32_e8e9_bswap_le, s_ctok32_e8e9_bswap_le },
|
||||
{ 0x49, 6, 0x00ffffff, f_ctok32_e8e9_bswap_le, u_ctok32_e8e9_bswap_le, s_ctok32_e8e9_bswap_le },
|
||||
|
||||
// 24-bit calltrick for arm
|
||||
{ 0x50, 8, 0x01ffffff, f_ct24arm_le, u_ct24arm_le, s_ct24arm_le },
|
||||
{ 0x51, 8, 0x01ffffff, f_ct24arm_be, u_ct24arm_be, s_ct24arm_be },
|
||||
|
||||
// 32-bit cto calltrick with jmp and jcc(swap 0x0f/0x8Y) and relative renumbering
|
||||
{ 0x80, 8, 0x00ffffff, f_ctojr32_e8e9_bswap_le, u_ctojr32_e8e9_bswap_le, s_ctojr32_e8e9_bswap_le },
|
||||
{ 0x81, 8, 0x00ffffff, f_ctojr32_e8e9_bswap_le, u_ctojr32_e8e9_bswap_le, s_ctojr32_e8e9_bswap_le },
|
||||
@@ -230,6 +253,9 @@ const FilterImp::FilterEntry FilterImp::filters[] = {
|
||||
{ 0xb1,99, 0, f_sub32_2, u_sub32_2, s_sub32_2 },
|
||||
{ 0xb2,99, 0, f_sub32_3, u_sub32_3, s_sub32_3 },
|
||||
{ 0xb3,99, 0, f_sub32_4, u_sub32_4, s_sub32_4 },
|
||||
|
||||
// PowerPC branch+call trick
|
||||
{ 0xd0, 8, 0, f_ppcbxx, u_ppcbxx, s_ppcbxx },
|
||||
};
|
||||
|
||||
const int FilterImp::n_filters = TABLESIZE(filters);
|
||||
|
||||
+29
-21
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2005 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2005 Laszlo Molnar
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -47,9 +47,9 @@ void show_head(void)
|
||||
#define V(x) (strcmp(UPX_VERSION_STRING, UPX_VERSION_STRING4) ? UPX_VERSION_STRING : UPX_VERSION_STRING x)
|
||||
fg = con_fg(f,FG_GREEN);
|
||||
con_fprintf(f,
|
||||
" Ultimate Packer for eXecutables\n"
|
||||
" Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005\n"
|
||||
"UPX %-12s Markus F.X.J. Oberhumer & Laszlo Molnar %20s\n\n",
|
||||
" Ultimate Packer for eXecutables\n"
|
||||
" Copyright (C) 1996,1997,1998,1999,2000,2001,2002,2003,2004,2005,2006\n"
|
||||
"UPX %-10s Markus Oberhumer, Laszlo Molnar & John Reiser %14s\n\n",
|
||||
#if (ACC_OS_DOS16 || ACC_OS_DOS32)
|
||||
V("d"),
|
||||
#elif (ACC_OS_WIN16 || ACC_OS_WIN32 || ACC_OS_WIN64)
|
||||
@@ -196,7 +196,8 @@ void show_help(int x)
|
||||
con_fprintf(f,
|
||||
" --all-methods try all available compression methods\n"
|
||||
" --8-bit uses 8 bit size compression [default: 32 bit]\n"
|
||||
" --console-run enables client/host transfer compatibility\n"
|
||||
" --8mb-ram 8 megabyte memory limit [default: 2 mb]\n"
|
||||
" --boot-only disables client/host transfer compatibility\n"
|
||||
" --no-align don't align to 2048 bytes [enables: --console-run]\n"
|
||||
"\n");
|
||||
fg = con_fg(f,FG_YELLOW);
|
||||
@@ -229,8 +230,7 @@ void show_help(int x)
|
||||
" --compress-icons=1 compress all but the first icon\n"
|
||||
" --compress-icons=2 compress all but the first icon directory [default]\n"
|
||||
" --compress-resources=0 do not compress any resources at all\n"
|
||||
" --strip-loadconf=0 do not strip SEH load config [default]\n"
|
||||
" --strip-loadconf=1 strip SEH load config [DANGEROUS]\n"
|
||||
" --keep-resource=list do not compress resources specified by list\n"
|
||||
" --strip-relocs=0 do not strip relocations\n"
|
||||
" --strip-relocs=1 strip relocations [default]\n"
|
||||
" --all-methods try all available compression methods\n"
|
||||
@@ -245,6 +245,11 @@ void show_help(int x)
|
||||
con_fprintf(f,"This version supports:\n");
|
||||
fg = con_fg(f,fg);
|
||||
con_fprintf(f," "
|
||||
// TODO:
|
||||
// support for mach/ppc32
|
||||
// support for linux elf/ppc32
|
||||
// support for linux elf/amd64
|
||||
" arm/pe,"
|
||||
" atari/tos,"
|
||||
" bvmlinuz/386,"
|
||||
" djgpp2/coff,"
|
||||
@@ -253,20 +258,21 @@ void show_help(int x)
|
||||
" dos/sys,"
|
||||
"\n "
|
||||
//" elks/8086,"
|
||||
" linux/386,"
|
||||
" linux/elf386,"
|
||||
" linux/sh386,"
|
||||
" linux/amd64,"
|
||||
" linux/i386,"
|
||||
" linux/ppc32,"
|
||||
" mach/ppc32,"
|
||||
" ps1/exe,"
|
||||
" rtm32/pe,"
|
||||
" tmt/adam,"
|
||||
"\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"
|
||||
// "\n\nUPX comes with ABSOLUTELY NO WARRANTY; for details type `upx -L'.\n"
|
||||
"");
|
||||
|
||||
|
||||
@@ -337,21 +343,23 @@ void show_version(int x)
|
||||
FILE *f = stdout;
|
||||
UNUSED(x);
|
||||
|
||||
#if (0 && ACC_CC_GNUC)
|
||||
fprintf(f,"upx %s (gcc 0x%06lx)\n", UPX_VERSION_STRING, ACC_CC_GNUC);
|
||||
#else
|
||||
fprintf(f,"upx %s\n", UPX_VERSION_STRING);
|
||||
#endif
|
||||
#if defined(WITH_NRV)
|
||||
fprintf(f,"NRV data compression library %s\n", nrv_version_string());
|
||||
#endif
|
||||
#if defined(WITH_UCL)
|
||||
fprintf(f,"UCL data compression library %s\n", ucl_version_string());
|
||||
#endif
|
||||
fprintf(f,"Copyright (C) 1996-2005 Markus Franz Xaver Johannes Oberhumer\n");
|
||||
fprintf(f,"Copyright (C) 1996-2005 Laszlo Molnar\n");
|
||||
fprintf(f,"Copyright (C) 2000-2005 John F. Reiser\n");
|
||||
fprintf(f,"Copyright (C) 2002-2005 Jens Medoch\n");
|
||||
#if 0 && defined(WITH_LZMA)
|
||||
fprintf(f,"LZMA SDK version ???\n");
|
||||
#endif
|
||||
fprintf(f,"Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer\n");
|
||||
fprintf(f,"Copyright (C) 1996-2006 Laszlo Molnar\n");
|
||||
fprintf(f,"Copyright (C) 2000-2006 John F. Reiser\n");
|
||||
fprintf(f,"Copyright (C) 2002-2006 Jens Medoch\n");
|
||||
#if defined(WITH_LZMA)
|
||||
fprintf(f,"Copyright (C) 1999-2006 Igor Pavlov\n");
|
||||
#endif
|
||||
fprintf(f,"UPX comes with ABSOLUTELY NO WARRANTY; for details type `%s -L'.\n", progname);
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -2,8 +2,8 @@
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2004 Laszlo Molnar
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
|
||||
+2
-2
@@ -2,8 +2,8 @@
|
||||
|
||||
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) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
|
||||
+617
-152
@@ -2,8 +2,8 @@
|
||||
|
||||
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) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -22,194 +22,659 @@
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
markus@oberhumer.com ml1050@cdata.tvnet.hu
|
||||
markus@oberhumer.com ml1050@users.sourceforge.net
|
||||
*/
|
||||
|
||||
|
||||
#include "conf.h"
|
||||
#include "linker.h"
|
||||
|
||||
|
||||
struct Linker::section
|
||||
{
|
||||
int istart;
|
||||
int ostart;
|
||||
int len;
|
||||
char name[8];
|
||||
};
|
||||
|
||||
struct Linker::jump
|
||||
{
|
||||
int pos;
|
||||
int len;
|
||||
char tsect[8];
|
||||
int toffs;
|
||||
};
|
||||
|
||||
Linker::Linker(const void *pdata, int plen, int pinfo)
|
||||
{
|
||||
iloader = new char[(ilen = plen) + 4096];
|
||||
memcpy(iloader,pdata,plen);
|
||||
oloader = new char[plen];
|
||||
olen = 0;
|
||||
align_hack = 0;
|
||||
align_offset = 0;
|
||||
info = pinfo;
|
||||
njumps = nsections = frozen = 0;
|
||||
jumps = new jump[200];
|
||||
#define NSECTIONS 350
|
||||
sections = new section[NSECTIONS];
|
||||
|
||||
char *p = iloader + info;
|
||||
while (get32(p) != (unsigned)(-1))
|
||||
{
|
||||
if (get32(p))
|
||||
{
|
||||
memcpy(sections[nsections].name,p,8);
|
||||
sections[nsections].istart = get32(p+8);
|
||||
sections[nsections++].ostart = -1;
|
||||
p += 12;
|
||||
assert(nsections < NSECTIONS);
|
||||
}
|
||||
else
|
||||
{
|
||||
int l;
|
||||
for (l = get32(p+4) - 1; iloader[l] == 0; l--)
|
||||
;
|
||||
|
||||
jumps[njumps].pos = l+1;
|
||||
jumps[njumps].len = get32(p+4)-jumps[njumps].pos;
|
||||
memcpy(jumps[njumps].tsect,p+8,8);
|
||||
jumps[njumps++].toffs = get32(p+16);
|
||||
p += 20;
|
||||
assert(njumps < 200);
|
||||
}
|
||||
}
|
||||
|
||||
int ic;
|
||||
for (ic = 0; ic < nsections - 1; ic++)
|
||||
sections[ic].len = sections[ic+1].istart - sections[ic].istart;
|
||||
sections[ic].len = 0;
|
||||
}
|
||||
|
||||
|
||||
Linker::~Linker()
|
||||
{
|
||||
delete [] iloader;
|
||||
delete [] oloader;
|
||||
delete [] jumps;
|
||||
delete [] sections;
|
||||
}
|
||||
|
||||
|
||||
void Linker::setLoaderAlignOffset(int offset)
|
||||
{
|
||||
align_offset = offset;
|
||||
}
|
||||
|
||||
static int hex(char c)
|
||||
static int hex(unsigned char c)
|
||||
{
|
||||
return (c & 0xf) + (c > '9' ? 9 : 0);
|
||||
}
|
||||
|
||||
int Linker::addSection(const char *sect)
|
||||
static bool update_capacity(unsigned size, unsigned *capacity)
|
||||
{
|
||||
int ic;
|
||||
while (*sect)
|
||||
if (size < *capacity)
|
||||
return false;
|
||||
if (*capacity == 0)
|
||||
*capacity = 16;
|
||||
while (size >= *capacity)
|
||||
*capacity *= 2;
|
||||
return true;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
ElfLinker::Section::Section(const char *n, const void *i, unsigned s, unsigned a) :
|
||||
name(strdup(n)), output(NULL), size(s), offset(0), align(a), next(NULL)
|
||||
{
|
||||
assert(name);
|
||||
input = malloc(s + 1);
|
||||
assert(input);
|
||||
memcpy(input, i, s);
|
||||
}
|
||||
|
||||
ElfLinker::Section::~Section()
|
||||
{
|
||||
free(name);
|
||||
free(input);
|
||||
}
|
||||
|
||||
ElfLinker::Symbol::Symbol(const char *n, Section *s, unsigned o) :
|
||||
name(strdup(n)), section(s), offset(o)
|
||||
{
|
||||
assert(name);
|
||||
}
|
||||
|
||||
ElfLinker::Symbol::~Symbol()
|
||||
{
|
||||
free(name);
|
||||
}
|
||||
|
||||
ElfLinker::Relocation::Relocation(const Section *s, unsigned o, const char *t,
|
||||
const Symbol *v, unsigned a) :
|
||||
section(s), offset(o), type(t), value(v), add(a)
|
||||
{}
|
||||
|
||||
|
||||
void ElfLinker::preprocessSections(char *start, const char *end)
|
||||
{
|
||||
nsections = 0;
|
||||
while (start < end)
|
||||
{
|
||||
char name[1024];
|
||||
unsigned offset, size, align;
|
||||
|
||||
char *nextl = strchr(start, '\n');
|
||||
assert(nextl != NULL);
|
||||
|
||||
if (sscanf(start, "%*d %1023s %x %*d %*d %x 2**%d",
|
||||
name, &size, &offset, &align) == 4)
|
||||
{
|
||||
char *n = strstr(start, name);
|
||||
n[strlen(name)] = 0;
|
||||
addSection(n, input + offset, size, align);
|
||||
|
||||
//printf("section %s preprocessed\n", n);
|
||||
}
|
||||
start = nextl + 1;
|
||||
}
|
||||
addSection("*ABS*", NULL, 0, 0);
|
||||
addSection("*UND*", NULL, 0, 0);
|
||||
}
|
||||
|
||||
void ElfLinker::preprocessSymbols(char *start, const char *end)
|
||||
{
|
||||
nsymbols = 0;
|
||||
while (start < end)
|
||||
{
|
||||
char section[1024];
|
||||
char symbol[1024];
|
||||
unsigned offset;
|
||||
|
||||
char *nextl = strchr(start, '\n');
|
||||
assert(nextl != NULL);
|
||||
|
||||
if (sscanf(start, "%x%*8c %1024s %*x %1023s",
|
||||
&offset, section, symbol) == 3)
|
||||
{
|
||||
char *s = strstr(start, symbol);
|
||||
s[strlen(symbol)] = 0;
|
||||
|
||||
if (strcmp(section, "*UND*") == 0)
|
||||
offset = 0xdeaddead;
|
||||
addSymbol(s, section, offset);
|
||||
|
||||
//printf("symbol %s preprocessed o=%x\n", s, offset);
|
||||
}
|
||||
|
||||
start = nextl + 1;
|
||||
}
|
||||
}
|
||||
|
||||
void ElfLinker::preprocessRelocations(char *start, const char *end)
|
||||
{
|
||||
char sect[1024];
|
||||
Section *section = NULL;
|
||||
|
||||
nrelocations = 0;
|
||||
while (start < end)
|
||||
{
|
||||
if (sscanf(start, "RELOCATION RECORDS FOR [%[^]]", sect) == 1)
|
||||
section = findSection(sect);
|
||||
|
||||
unsigned offset;
|
||||
char type[100];
|
||||
char symbol[1024];
|
||||
|
||||
char *nextl = strchr(start, '\n');
|
||||
assert(nextl != NULL);
|
||||
|
||||
if (sscanf(start, "%x %99s %1023s",
|
||||
&offset, type, symbol) == 3)
|
||||
{
|
||||
char *t = strstr(start, type);
|
||||
t[strlen(type)] = 0;
|
||||
|
||||
unsigned add = 0;
|
||||
if (char *p = strstr(symbol, "+0x"))
|
||||
{
|
||||
// Beware: sscanf("0xfffffffffffffffc", "%x", &add) ==> -1 == add
|
||||
// because conversion stops after 32 bits for a non-long.
|
||||
// Also, glibc-2.3.5 has a bug: even using "%lx" still gives -1 instead of -4.
|
||||
long addend;
|
||||
*p = 0; // terminate the symbol name
|
||||
p+=3;
|
||||
if ('f'==p[0] && 0==strncmp(p, "ffffffff", 8)) {
|
||||
p+=8; // workaround a bug in glibc-2.3.5
|
||||
}
|
||||
sscanf(p, "%lx", &addend);
|
||||
add = (unsigned)addend;
|
||||
}
|
||||
|
||||
addRelocation(section->name, offset, t, symbol, add);
|
||||
|
||||
//printf("relocation %s %x preprocessed\n", section->name, offset);
|
||||
}
|
||||
|
||||
start = nextl + 1;
|
||||
}
|
||||
}
|
||||
|
||||
ElfLinker::Section *ElfLinker::findSection(const char *name) const
|
||||
{
|
||||
for (unsigned ic = 0; ic < nsections; ic++)
|
||||
if (strcmp(sections[ic]->name, name) == 0)
|
||||
return sections[ic];
|
||||
|
||||
printf("unknown section %s\n", name);
|
||||
abort();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ElfLinker::Symbol *ElfLinker::findSymbol(const char *name) /*const*/
|
||||
{
|
||||
for (unsigned ic = 0; ic < nsymbols; ic++)
|
||||
if (strcmp(symbols[ic]->name, name) == 0)
|
||||
return symbols[ic];
|
||||
|
||||
// FIXME: this should be a const method !
|
||||
if ('*' == name[0]) // *ABS*
|
||||
return addSymbol(name, name, 0);
|
||||
|
||||
printf("unknown symbol %s\n", name);
|
||||
abort();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ElfLinker::Symbol *ElfLinker::addSymbol(const char *name, const char *section,
|
||||
unsigned offset)
|
||||
{
|
||||
if (update_capacity(nsymbols, &nsymbols_capacity))
|
||||
symbols = static_cast<Symbol **>(realloc(symbols, nsymbols_capacity * sizeof(Symbol *)));
|
||||
assert(symbols != NULL);
|
||||
Symbol *sym = new Symbol(name, findSection(section), offset);
|
||||
symbols[nsymbols++] = sym;
|
||||
return sym;
|
||||
}
|
||||
|
||||
ElfLinker::Relocation *ElfLinker::addRelocation(const char *section, unsigned off,
|
||||
const char *type, const char *symbol,
|
||||
unsigned add)
|
||||
{
|
||||
if (update_capacity(nrelocations, &nrelocations_capacity))
|
||||
relocations = static_cast<Relocation **>(realloc(relocations, (nrelocations_capacity) * sizeof(Relocation *)));
|
||||
assert(relocations != NULL);
|
||||
Relocation *rel = new Relocation(findSection(section), off,
|
||||
type, findSymbol(symbol), add);
|
||||
relocations[nrelocations++] = rel;
|
||||
return rel;
|
||||
}
|
||||
|
||||
ElfLinker::ElfLinker() :
|
||||
frozen(false), input(NULL), output(NULL), head(NULL), tail(NULL),
|
||||
sections(NULL), symbols(NULL), relocations(NULL),
|
||||
nsections(0), nsections_capacity(0),
|
||||
nsymbols(0), nsymbols_capacity(0),
|
||||
nrelocations(0), nrelocations_capacity(0)
|
||||
{
|
||||
}
|
||||
|
||||
ElfLinker::~ElfLinker()
|
||||
{
|
||||
delete [] input;
|
||||
delete [] output;
|
||||
|
||||
unsigned ic;
|
||||
for (ic = 0; ic < nsections; ic++)
|
||||
delete sections[ic];
|
||||
free(sections);
|
||||
for (ic = 0; ic < nsymbols; ic++)
|
||||
delete symbols[ic];
|
||||
free(symbols);
|
||||
for (ic = 0; ic < nrelocations; ic++)
|
||||
delete relocations[ic];
|
||||
free(relocations);
|
||||
}
|
||||
|
||||
void ElfLinker::init(const void *pdata, int plen)
|
||||
{
|
||||
upx_byte *i = new upx_byte[plen + 1];
|
||||
memcpy(i, pdata, plen);
|
||||
input = i;
|
||||
inputlen = plen;
|
||||
|
||||
output = new upx_byte[plen];
|
||||
outputlen = 0;
|
||||
|
||||
int pos = find(input, plen, "Sections:", 9);
|
||||
assert(pos != -1);
|
||||
char *psections = pos + (char *) input;
|
||||
|
||||
char *psymbols = strstr(psections, "SYMBOL TABLE:");
|
||||
assert(psymbols != NULL);
|
||||
|
||||
char *prelocs = strstr(psymbols, "RELOCATION RECORDS FOR");
|
||||
assert(prelocs != NULL);
|
||||
input[plen] = 0;
|
||||
|
||||
preprocessSections(psections, psymbols);
|
||||
preprocessSymbols(psymbols, prelocs);
|
||||
preprocessRelocations(prelocs, (char*) input + inputlen);
|
||||
addLoader("*UND*");
|
||||
}
|
||||
|
||||
void ElfLinker::setLoaderAlignOffset(int phase)
|
||||
{
|
||||
//assert(phase & 0);
|
||||
printf("\nFIXME: ElfLinker::setLoaderAlignOffset %d\n", phase);
|
||||
}
|
||||
|
||||
int ElfLinker::addLoader(const char *sname)
|
||||
{
|
||||
assert(!frozen);
|
||||
if (sname[0] == 0)
|
||||
return outputlen;
|
||||
|
||||
char *begin = strdup(sname);
|
||||
char *end = begin + strlen(begin);
|
||||
for (char *sect = begin; sect < end; )
|
||||
{
|
||||
for (char *tokend = sect; *tokend; tokend++)
|
||||
if (*tokend == ' ' || *tokend == ',')
|
||||
{
|
||||
*tokend = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (*sect == '+') // alignment
|
||||
{
|
||||
if (sect[1] == '0')
|
||||
align_hack = olen + align_offset;
|
||||
else
|
||||
assert(tail);
|
||||
if (unsigned l = (hex(sect[2]) - tail->offset - tail->size)
|
||||
% hex(sect[1]))
|
||||
{
|
||||
unsigned j = hex(sect[1]);
|
||||
j = (hex(sect[2]) - ((olen + align_offset) - align_hack) ) % j;
|
||||
memset(oloader+olen, (sect[3] == 'C' ? 0x90 : 0), j);
|
||||
olen += j;
|
||||
alignCode(l);
|
||||
tail->size += l;
|
||||
outputlen += l;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (ic = 0; ic < nsections; ic++)
|
||||
if (memcmp(sect,sections[ic].name,8) == 0)
|
||||
{
|
||||
memcpy(oloader+olen,iloader+sections[ic].istart,sections[ic].len);
|
||||
sections[ic].ostart = olen;
|
||||
olen += sections[ic].len;
|
||||
break;
|
||||
Section *section = findSection(sect);
|
||||
if (section->align) {
|
||||
unsigned const v = ~0u << section->align;
|
||||
assert(tail);
|
||||
if (unsigned const l = ~v & -(tail->offset + tail->size)) {
|
||||
alignCode(l);
|
||||
tail->size += l;
|
||||
outputlen += l;
|
||||
}
|
||||
//printf("%8.8s",sect);
|
||||
assert(ic!=nsections);
|
||||
}
|
||||
memcpy(output + outputlen, section->input, section->size);
|
||||
section->output = output + outputlen;
|
||||
outputlen += section->size;
|
||||
//printf("section added: %s\n", sect);
|
||||
|
||||
if (head)
|
||||
{
|
||||
tail->next = section;
|
||||
section->offset = tail->offset + tail->size;
|
||||
}
|
||||
else
|
||||
head = section;
|
||||
tail = section;
|
||||
}
|
||||
sect += 8;
|
||||
sect += strlen(sect) + 1;
|
||||
}
|
||||
return olen;
|
||||
free(begin);
|
||||
return outputlen;
|
||||
}
|
||||
|
||||
|
||||
void Linker::addSection(const char *sname, const void *sdata, unsigned len)
|
||||
void ElfLinker::addSection(const char *sname, const void *sdata, int slen, int align)
|
||||
{
|
||||
// add a new section - can be used for adding stuff like ident or header
|
||||
memcpy(sections[nsections].name,sname,8);
|
||||
sections[nsections].istart = ilen;
|
||||
sections[nsections].len = len;
|
||||
sections[nsections++].ostart = olen;
|
||||
assert(nsections < NSECTIONS);
|
||||
memcpy(iloader+ilen,sdata,len);
|
||||
ilen += len;
|
||||
assert(!frozen);
|
||||
if (update_capacity(nsections, &nsections_capacity))
|
||||
sections = static_cast<Section **>(realloc(sections, nsections_capacity * sizeof(Section *)));
|
||||
assert(sections);
|
||||
Section *sec = new Section(sname, sdata, slen, align);
|
||||
sections[nsections++] = sec;
|
||||
//return sec;
|
||||
}
|
||||
|
||||
|
||||
const char *Linker::getLoader(int *llen)
|
||||
void ElfLinker::freeze()
|
||||
{
|
||||
if (!frozen)
|
||||
if (frozen)
|
||||
return;
|
||||
|
||||
frozen = true;
|
||||
}
|
||||
|
||||
int ElfLinker::getSection(const char *sname, int *slen)
|
||||
{
|
||||
assert(frozen);
|
||||
Section *section = findSection(sname);
|
||||
if (slen)
|
||||
*slen = section->size;
|
||||
return section->output - output;
|
||||
}
|
||||
|
||||
upx_byte *ElfLinker::getLoader(int *llen)
|
||||
{
|
||||
assert(frozen);
|
||||
|
||||
if (llen)
|
||||
*llen = outputlen;
|
||||
return output;
|
||||
}
|
||||
|
||||
void ElfLinker::relocate()
|
||||
{
|
||||
assert(frozen);
|
||||
|
||||
for (unsigned ic = 0; ic < nrelocations; ic++)
|
||||
{
|
||||
int ic,jc,kc;
|
||||
for (ic = 0; ic < njumps; ic++)
|
||||
Relocation *rel = relocations[ic];
|
||||
if (rel->section->output == NULL)
|
||||
continue;
|
||||
if (rel->value->section->output == NULL)
|
||||
{
|
||||
for (jc = 0; jc < nsections-1; jc++)
|
||||
if (jumps[ic].pos >= sections[jc].istart
|
||||
&& jumps[ic].pos < sections[jc+1].istart)
|
||||
break;
|
||||
assert(jc!=nsections-1);
|
||||
if (sections[jc].ostart < 0)
|
||||
continue;
|
||||
|
||||
for (kc = 0; kc < nsections-1; kc++)
|
||||
if (memcmp(jumps[ic].tsect,sections[kc].name,8) == 0)
|
||||
break;
|
||||
assert(kc!=nsections-1);
|
||||
|
||||
int offs = sections[kc].ostart+jumps[ic].toffs -
|
||||
(jumps[ic].pos+jumps[ic].len -
|
||||
sections[jc].istart+sections[jc].ostart);
|
||||
|
||||
if (jumps[ic].len == 1)
|
||||
assert(-128 <= offs && offs <= 127);
|
||||
|
||||
set32(&offs,offs);
|
||||
memcpy(oloader+sections[jc].ostart+jumps[ic].pos-sections[jc].istart,&offs,jumps[ic].len);
|
||||
printf("can not apply reloc '%s:%x' without section '%s'\n",
|
||||
rel->section->name, rel->offset,
|
||||
rel->value->section->name);
|
||||
abort();
|
||||
}
|
||||
frozen=1;
|
||||
|
||||
if (strcmp(rel->value->section->name, "*UND*") == 0 &&
|
||||
rel->value->offset == 0xdeaddead)
|
||||
{
|
||||
printf("undefined symbol '%s' referenced\n", rel->value->name);
|
||||
abort();
|
||||
}
|
||||
unsigned value = rel->value->section->offset +
|
||||
rel->value->offset + rel->add;
|
||||
upx_byte *location = rel->section->output + rel->offset;
|
||||
|
||||
relocate1(rel, location, value, rel->type);
|
||||
}
|
||||
if (llen) *llen = olen;
|
||||
return oloader;
|
||||
}
|
||||
|
||||
void ElfLinker::defineSymbol(const char *name, unsigned value)
|
||||
{
|
||||
Symbol *symbol = findSymbol(name);
|
||||
if (strcmp(symbol->section->name, "*UND*") == 0) // for undefined symbols
|
||||
symbol->offset = value;
|
||||
else if (strcmp(symbol->section->name, name) == 0) // for sections
|
||||
{
|
||||
for (Section *section = symbol->section; section; section = section->next)
|
||||
{
|
||||
assert(section->offset < value);
|
||||
section->offset = value;
|
||||
value += section->size;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("symbol '%s' already defined\n", name);
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
// debugging support
|
||||
void ElfLinker::dumpSymbols(FILE *fp) const
|
||||
{
|
||||
if (fp == NULL)
|
||||
fp = stdout;
|
||||
for (unsigned ic = 0; ic < nsymbols; ic++)
|
||||
{
|
||||
Symbol *symbol = symbols[ic];
|
||||
fprintf(fp, "%-20s 0x%08x | %-20s 0x%08x\n",
|
||||
symbol->name, symbol->offset, symbol->section->name, symbol->section->offset);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned ElfLinker::getSymbolOffset(const char *name) const
|
||||
{
|
||||
assert(frozen);
|
||||
Symbol *symbol = const_cast<ElfLinker *>(this)->findSymbol(name);
|
||||
if (symbol->section->output == NULL)
|
||||
return 0xdeaddead;
|
||||
return symbol->section->offset + symbol->offset;
|
||||
}
|
||||
|
||||
void ElfLinker::alignWithByte(unsigned len, upx_byte b)
|
||||
{
|
||||
memset(output + outputlen, b, len);
|
||||
}
|
||||
|
||||
void ElfLinker::relocate1(const Relocation *rel, upx_byte *,
|
||||
unsigned, const char *)
|
||||
{
|
||||
printf("unknown relocation type '%s\n", rel->type);
|
||||
abort();
|
||||
}
|
||||
|
||||
|
||||
int Linker::getSection(const char *name, int *slen) const
|
||||
/*************************************************************************
|
||||
// ElfLinker arch subclasses
|
||||
// FIXME: add more displacment overflow checks
|
||||
**************************************************************************/
|
||||
|
||||
void ElfLinkerAMD64::relocate1(const Relocation *rel, upx_byte *location,
|
||||
unsigned value, const char *type)
|
||||
{
|
||||
if (!frozen)
|
||||
return -1;
|
||||
for (int ic = 0; ic < nsections; ic++)
|
||||
if (memcmp(name,sections[ic].name,8) == 0)
|
||||
if (strncmp(type, "R_X86_64_", 9))
|
||||
return super::relocate1(rel, location, value, type);
|
||||
type += 9;
|
||||
|
||||
if (strncmp(type, "PC", 2) == 0)
|
||||
{
|
||||
value -= rel->section->offset + rel->offset;
|
||||
type += 2;
|
||||
}
|
||||
|
||||
if (strcmp(type, "8") == 0)
|
||||
{
|
||||
int displ = (signed char) *location + (int) value;
|
||||
if (displ < -128 || displ > 127)
|
||||
{
|
||||
if (slen)
|
||||
*slen = sections[ic].len;
|
||||
return sections[ic].ostart;
|
||||
printf("target out of range (%d) in reloc %s:%x\n",
|
||||
displ, rel->section->name, rel->offset);
|
||||
abort();
|
||||
}
|
||||
return -1;
|
||||
*location += value;
|
||||
}
|
||||
else if (strcmp(type, "16") == 0)
|
||||
set_le16(location, get_le16(location) + value);
|
||||
else if (strcmp(type, "32") == 0)
|
||||
set_le32(location, get_le32(location) + value);
|
||||
else
|
||||
super::relocate1(rel, location, value, type);
|
||||
}
|
||||
|
||||
|
||||
void ElfLinkerArmBE::relocate1(const Relocation *rel, upx_byte *location,
|
||||
unsigned value, const char *type)
|
||||
{
|
||||
if (strcmp(type, "R_ARM_PC24") == 0)
|
||||
{
|
||||
value -= rel->section->offset + rel->offset;
|
||||
set_be24(1+ location, get_be24(1+ location) + value / 4);
|
||||
}
|
||||
else if (strcmp(type, "R_ARM_ABS32") == 0)
|
||||
{
|
||||
set_be32(location, get_be32(location) + value);
|
||||
}
|
||||
else if (strcmp(type, "R_ARM_THM_CALL") == 0)
|
||||
{
|
||||
value -= rel->section->offset + rel->offset;
|
||||
value += ((get_be16(location) & 0x7ff) << 12);
|
||||
value += (get_be16(location + 2) & 0x7ff) << 1;
|
||||
|
||||
set_be16(location, 0xf000 + ((value >> 12) & 0x7ff));
|
||||
set_be16(location + 2, 0xf800 + ((value >> 1) & 0x7ff));
|
||||
|
||||
//(b, 0xF000 + ((v - 1) / 2) * 0x10000);
|
||||
//set_be32(location, get_be32(location) + value / 4);
|
||||
}
|
||||
else
|
||||
super::relocate1(rel, location, value, type);
|
||||
}
|
||||
|
||||
|
||||
void ElfLinkerArmLE::relocate1(const Relocation *rel, upx_byte *location,
|
||||
unsigned value, const char *type)
|
||||
{
|
||||
if (strcmp(type, "R_ARM_PC24") == 0)
|
||||
{
|
||||
value -= rel->section->offset + rel->offset;
|
||||
set_le24(location, get_le24(location) + value / 4);
|
||||
}
|
||||
else if (strcmp(type, "R_ARM_ABS32") == 0)
|
||||
{
|
||||
set_le32(location, get_le32(location) + value);
|
||||
}
|
||||
else if (strcmp(type, "R_ARM_THM_CALL") == 0)
|
||||
{
|
||||
value -= rel->section->offset + rel->offset;
|
||||
value += ((get_le16(location) & 0x7ff) << 12);
|
||||
value += (get_le16(location + 2) & 0x7ff) << 1;
|
||||
|
||||
set_le16(location, 0xf000 + ((value >> 12) & 0x7ff));
|
||||
set_le16(location + 2, 0xf800 + ((value >> 1) & 0x7ff));
|
||||
|
||||
//(b, 0xF000 + ((v - 1) / 2) * 0x10000);
|
||||
//set_le32(location, get_le32(location) + value / 4);
|
||||
}
|
||||
else
|
||||
super::relocate1(rel, location, value, type);
|
||||
}
|
||||
|
||||
|
||||
void ElfLinkerM68k::alignCode(unsigned len)
|
||||
{
|
||||
assert((len & 1) == 0);
|
||||
assert((outputlen & 1) == 0);
|
||||
for (unsigned i = 0; i < len; i += 2)
|
||||
set_be16(output + outputlen + i, 0x4e71); // "nop"
|
||||
}
|
||||
|
||||
void ElfLinkerM68k::relocate1(const Relocation *rel, upx_byte *location,
|
||||
unsigned value, const char *type)
|
||||
{
|
||||
if (strncmp(type, "R_68K_", 6))
|
||||
return super::relocate1(rel, location, value, type);
|
||||
type += 6;
|
||||
|
||||
if (strncmp(type, "PC", 2) == 0)
|
||||
{
|
||||
value -= rel->section->offset + rel->offset;
|
||||
type += 2;
|
||||
}
|
||||
if (strcmp(type, "8") == 0)
|
||||
*location += value;
|
||||
else if (strcmp(type, "16") == 0)
|
||||
set_be16(location, get_be16(location) + value);
|
||||
else if (strcmp(type, "32") == 0)
|
||||
set_be32(location, get_be32(location) + value);
|
||||
else
|
||||
super::relocate1(rel, location, value, type);
|
||||
}
|
||||
|
||||
|
||||
void ElfLinkerPpc32::relocate1(const Relocation *rel, upx_byte *location,
|
||||
unsigned value, const char *type)
|
||||
{
|
||||
if (strncmp(type, "R_PPC_", 6))
|
||||
return super::relocate1(rel, location, value, type);
|
||||
type += 6;
|
||||
|
||||
if (strncmp(type, "REL", 3) == 0)
|
||||
{
|
||||
value -= rel->section->offset + rel->offset;
|
||||
type += 3;
|
||||
}
|
||||
|
||||
// FIXME: more relocs
|
||||
|
||||
// Note that original (*location).displ is ignored.
|
||||
if (strcmp(type, "24") == 0) {
|
||||
if (3& value) {
|
||||
printf("unaligned word diplacement");
|
||||
abort();
|
||||
}
|
||||
// FIXME: displacment overflow?
|
||||
set_be32(location, (0xfc000003 & get_be32(location)) +
|
||||
(0x03fffffc & value));
|
||||
}
|
||||
else if (strcmp(type, "14") == 0) {
|
||||
if (3& value) {
|
||||
printf("unaligned word diplacement");
|
||||
abort();
|
||||
}
|
||||
// FIXME: displacment overflow?
|
||||
set_be32(location, (0xffff0003 & get_be32(location)) +
|
||||
(0x0000fffc & value));
|
||||
}
|
||||
else
|
||||
super::relocate1(rel, location, value, type);
|
||||
}
|
||||
|
||||
|
||||
void ElfLinkerX86::relocate1(const Relocation *rel, upx_byte *location,
|
||||
unsigned value, const char *type)
|
||||
{
|
||||
if (strncmp(type, "R_386_", 6))
|
||||
return super::relocate1(rel, location, value, type);
|
||||
type += 6;
|
||||
|
||||
int range_check = 0;
|
||||
if (strncmp(type, "PC", 2) == 0)
|
||||
{
|
||||
value -= rel->section->offset + rel->offset;
|
||||
type += 2;
|
||||
range_check = 1;
|
||||
}
|
||||
|
||||
if (strcmp(type, "8") == 0)
|
||||
{
|
||||
int displ = (signed char) *location + (int) value;
|
||||
if (range_check && (displ < -128 || displ > 127)) {
|
||||
printf("target out of range (%d) in reloc %s:%x\n",
|
||||
displ, rel->section->name, rel->offset);
|
||||
abort();
|
||||
}
|
||||
*location += value;
|
||||
}
|
||||
else if (strcmp(type, "16") == 0)
|
||||
set_le16(location, get_le16(location) + value);
|
||||
else if (strcmp(type, "32") == 0)
|
||||
set_le32(location, get_le32(location) + value);
|
||||
else
|
||||
super::relocate1(rel, location, value, type);
|
||||
}
|
||||
|
||||
|
||||
|
||||
+158
-48
@@ -2,8 +2,8 @@
|
||||
|
||||
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) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -22,7 +22,7 @@
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
markus@oberhumer.com ml1050@cdata.tvnet.hu
|
||||
markus@oberhumer.com ml1050@users.sourceforge.net
|
||||
*/
|
||||
|
||||
|
||||
@@ -30,64 +30,174 @@
|
||||
#define __UPX_LINKER_H
|
||||
|
||||
|
||||
class Linker
|
||||
/*************************************************************************
|
||||
// ElfLinker
|
||||
**************************************************************************/
|
||||
|
||||
class ElfLinker : private nocopy
|
||||
{
|
||||
public:
|
||||
Linker(const void *pdata, int plen, int pinfo);
|
||||
virtual ~Linker();
|
||||
int addSection(const char *sect);
|
||||
void addSection(const char *sname, const void *sdata, unsigned len);
|
||||
const char *getLoader(int *llen);
|
||||
int getSection(const char *name, int *slen) const;
|
||||
int getLoaderSize() const { return olen; }
|
||||
void setLoaderAlignOffset(int phase);
|
||||
|
||||
protected:
|
||||
// little endian
|
||||
virtual unsigned get32(const void *b) const { return get_le32(b); }
|
||||
virtual void set32(void *b, unsigned v) const { set_le32(b, v); }
|
||||
struct Section;
|
||||
struct Symbol;
|
||||
struct Relocation;
|
||||
|
||||
private:
|
||||
struct section;
|
||||
struct jump;
|
||||
bool frozen; // FIXME: can we remove this ?
|
||||
|
||||
char *iloader, *oloader;
|
||||
int ilen, olen;
|
||||
int info;
|
||||
jump *jumps;
|
||||
int njumps;
|
||||
section *sections;
|
||||
int nsections;
|
||||
int frozen;
|
||||
int align_hack;
|
||||
int align_offset;
|
||||
upx_byte *input;
|
||||
int inputlen;
|
||||
upx_byte *output;
|
||||
int outputlen;
|
||||
|
||||
private:
|
||||
// disable copy and assignment
|
||||
Linker(const Linker &); // {}
|
||||
Linker& operator= (const Linker &); // { return *this; }
|
||||
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;
|
||||
|
||||
void preprocessSections(char *start, const char *end);
|
||||
void preprocessSymbols(char *start, const char *end);
|
||||
void preprocessRelocations(char *start, const char *end);
|
||||
Section *findSection(const char *name) const;
|
||||
Symbol *findSymbol(const char *name) /*const*/;
|
||||
|
||||
Symbol *addSymbol(const char *name, const char *section, unsigned offset);
|
||||
Relocation *addRelocation(const char *section, unsigned off, const char *type,
|
||||
const char *symbol, unsigned add);
|
||||
|
||||
public:
|
||||
ElfLinker();
|
||||
virtual ~ElfLinker();
|
||||
|
||||
virtual void init(const void *pdata, int plen);
|
||||
virtual void setLoaderAlignOffset(int phase);
|
||||
virtual int addLoader(const char *sname);
|
||||
virtual void addSection(const char *sname, const void *sdata, int slen, int align);
|
||||
virtual void freeze();
|
||||
virtual int getSection(const char *sname, int *slen=NULL);
|
||||
virtual upx_byte *getLoader(int *llen=NULL);
|
||||
virtual void relocate();
|
||||
virtual void defineSymbol(const char *name, unsigned value);
|
||||
virtual unsigned getSymbolOffset(const char *) const;
|
||||
virtual void dumpSymbols(FILE *fp=NULL) const;
|
||||
|
||||
void alignWithByte(unsigned len, upx_byte b);
|
||||
virtual void alignCode(unsigned len) { alignWithByte(len, 0); }
|
||||
virtual void alignData(unsigned len) { alignWithByte(len, 0); }
|
||||
|
||||
virtual void relocate1(const Relocation *, upx_byte *location,
|
||||
unsigned value, const char *type);
|
||||
};
|
||||
|
||||
|
||||
class BeLinker : public Linker
|
||||
struct ElfLinker::Section : private nocopy
|
||||
{
|
||||
typedef Linker super;
|
||||
public:
|
||||
BeLinker(const void *pdata, int plen, int pinfo) :
|
||||
super(pdata, plen, pinfo) { }
|
||||
char *name;
|
||||
void *input;
|
||||
upx_byte *output;
|
||||
unsigned size;
|
||||
unsigned offset;
|
||||
unsigned char align; // log2
|
||||
Section *next;
|
||||
|
||||
protected:
|
||||
// big endian
|
||||
virtual unsigned get32(const void *b) const { return get_be32(b); }
|
||||
virtual void set32(void *b, unsigned v) const { set_be32(b, v); }
|
||||
|
||||
private:
|
||||
// disable copy and assignment
|
||||
BeLinker(const BeLinker &); // {}
|
||||
BeLinker& operator= (const BeLinker &); // { return *this; }
|
||||
Section(const char *n, const void *i, unsigned s, unsigned a=0);
|
||||
~Section();
|
||||
};
|
||||
|
||||
|
||||
struct ElfLinker::Symbol : private nocopy
|
||||
{
|
||||
char *name;
|
||||
Section *section;
|
||||
unsigned offset;
|
||||
|
||||
Symbol(const char *n, Section *s, unsigned o);
|
||||
~Symbol();
|
||||
};
|
||||
|
||||
|
||||
struct ElfLinker::Relocation : private nocopy
|
||||
{
|
||||
const Section *section;
|
||||
unsigned offset;
|
||||
const char *type;
|
||||
const Symbol *value;
|
||||
unsigned add; // used in .rela relocations
|
||||
|
||||
Relocation(const Section *s, unsigned o, const char *t,
|
||||
const Symbol *v, unsigned a);
|
||||
};
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// ElfLinker arch subclasses
|
||||
**************************************************************************/
|
||||
|
||||
class ElfLinkerAMD64 : public ElfLinker
|
||||
{
|
||||
typedef ElfLinker super;
|
||||
protected:
|
||||
virtual void alignCode(unsigned len) { alignWithByte(len, 0x90); }
|
||||
virtual void relocate1(const Relocation *, upx_byte *location,
|
||||
unsigned value, const char *type);
|
||||
};
|
||||
|
||||
|
||||
class ElfLinkerArmBE : public ElfLinker
|
||||
{
|
||||
typedef ElfLinker super;
|
||||
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;
|
||||
protected:
|
||||
virtual void alignCode(unsigned len);
|
||||
virtual void relocate1(const Relocation *, upx_byte *location,
|
||||
unsigned value, const char *type);
|
||||
};
|
||||
|
||||
|
||||
class ElfLinkerPpc32 : public ElfLinker
|
||||
{
|
||||
typedef ElfLinker super;
|
||||
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 */
|
||||
|
||||
|
||||
|
||||
+157
-50
@@ -2,8 +2,8 @@
|
||||
|
||||
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) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -30,6 +30,7 @@
|
||||
#include "mygetopt.h"
|
||||
#include "file.h"
|
||||
#include "packer.h"
|
||||
#include "p_elf.h"
|
||||
|
||||
|
||||
#if 1 && defined(__DJGPP__)
|
||||
@@ -45,7 +46,7 @@ int _crt0_startup_flags = _CRT0_FLAG_UNIX_SBRK;
|
||||
void init_options(struct options_t *o)
|
||||
{
|
||||
memset(o, 0, sizeof(*o));
|
||||
memset(&o->crp, 0xff, sizeof(o->crp));
|
||||
o->crp.reset();
|
||||
|
||||
o->cmd = CMD_NONE;
|
||||
o->method = -1;
|
||||
@@ -71,12 +72,12 @@ void init_options(struct options_t *o)
|
||||
for (unsigned i = 0; i < TABLESIZE(o->win32_pe.compress_rt); i++)
|
||||
o->win32_pe.compress_rt[i] = -1;
|
||||
o->win32_pe.compress_rt[24] = false; // 24 == RT_MANIFEST
|
||||
o->win32_pe.strip_loadconf = -1;
|
||||
o->win32_pe.strip_relocs = -1;
|
||||
o->win32_pe.keep_resource = "";
|
||||
}
|
||||
|
||||
static struct options_t global_options;
|
||||
struct options_t * volatile opt = &global_options;
|
||||
struct options_t *opt = &global_options;
|
||||
|
||||
static int done_output_name = 0;
|
||||
static int done_script_name = 0;
|
||||
@@ -444,7 +445,7 @@ static int do_option(int optc, const char *arg)
|
||||
set_cmd(CMD_DECOMPRESS);
|
||||
break;
|
||||
case 'D':
|
||||
opt->debug++;
|
||||
opt->debug.debug_level++;
|
||||
break;
|
||||
case 'f':
|
||||
opt->force++;
|
||||
@@ -511,6 +512,11 @@ static int do_option(int optc, const char *arg)
|
||||
if (!set_method(M_NRV2E_LE32, -1))
|
||||
e_method(M_NRV2E_LE32, opt->level);
|
||||
break;
|
||||
case 721:
|
||||
opt->all_methods_use_lzma = true;
|
||||
if (!set_method(M_LZMA, -1))
|
||||
e_method(M_LZMA, opt->level);
|
||||
break;
|
||||
|
||||
// compression level
|
||||
case '1':
|
||||
@@ -528,16 +534,34 @@ static int do_option(int optc, const char *arg)
|
||||
|
||||
case 901: // --brute
|
||||
opt->all_methods = true;
|
||||
opt->all_methods_use_lzma = true;
|
||||
opt->method = -1;
|
||||
opt->all_filters = true;
|
||||
opt->filter = -1;
|
||||
opt->crp.m_size = 999999;
|
||||
opt->crp.crp_ucl.m_size = 999999;
|
||||
/* fallthrough */
|
||||
case 900: // --best
|
||||
if (!set_method(-1, 10))
|
||||
e_method(opt->method, 10);
|
||||
break;
|
||||
|
||||
// debug
|
||||
case 542:
|
||||
if (!mfx_optarg || strlen(mfx_optarg) != 4)
|
||||
e_optarg(arg);
|
||||
memcpy(opt->debug.fake_stub_version, mfx_optarg, 4);
|
||||
break;
|
||||
case 543:
|
||||
if (!mfx_optarg || strlen(mfx_optarg) != 4)
|
||||
e_optarg(arg);
|
||||
memcpy(opt->debug.fake_stub_year, mfx_optarg, 4);
|
||||
break;
|
||||
case 544:
|
||||
if (!mfx_optarg || !mfx_optarg[0])
|
||||
e_optarg(arg);
|
||||
opt->debug.dump_stub_loader = mfx_optarg;
|
||||
break;
|
||||
|
||||
// misc
|
||||
case 512:
|
||||
opt->console = CON_FILE;
|
||||
@@ -567,6 +591,7 @@ static int do_option(int optc, const char *arg)
|
||||
case 522: // --no-filter
|
||||
opt->filter = 0;
|
||||
opt->all_filters = false;
|
||||
opt->no_filter = true;
|
||||
break;
|
||||
case 523: // --all-filters
|
||||
opt->all_filters = true;
|
||||
@@ -576,27 +601,27 @@ static int do_option(int optc, const char *arg)
|
||||
opt->all_methods = true;
|
||||
opt->method = -1;
|
||||
break;
|
||||
// compression parms
|
||||
// compression runtime parameters
|
||||
case 531:
|
||||
getoptvar(&opt->crp.c_flags, 0, 3);
|
||||
getoptvar(&opt->crp.crp_ucl.c_flags, 0, 3);
|
||||
break;
|
||||
case 532:
|
||||
getoptvar(&opt->crp.s_level, 0, 2);
|
||||
getoptvar(&opt->crp.crp_ucl.s_level, 0, 2);
|
||||
break;
|
||||
case 533:
|
||||
getoptvar(&opt->crp.h_level, 0, 1);
|
||||
getoptvar(&opt->crp.crp_ucl.h_level, 0, 1);
|
||||
break;
|
||||
case 534:
|
||||
getoptvar(&opt->crp.p_level, 0, 7);
|
||||
getoptvar(&opt->crp.crp_ucl.p_level, 0, 7);
|
||||
break;
|
||||
case 535:
|
||||
getoptvar(&opt->crp.max_offset, 256u, ~0u);
|
||||
getoptvar(&opt->crp.crp_ucl.max_offset, 256u, ~0u);
|
||||
break;
|
||||
case 536:
|
||||
getoptvar(&opt->crp.max_match, 16u, ~0u);
|
||||
getoptvar(&opt->crp.crp_ucl.max_match, 16u, ~0u);
|
||||
break;
|
||||
case 537:
|
||||
if (getoptvar(&opt->crp.m_size, 10000u, 999999u) != 0)
|
||||
if (getoptvar(&opt->crp.crp_ucl.m_size, 10000u, 999999u) != 0)
|
||||
e_optval("--crp-ms=");
|
||||
break;
|
||||
// backup
|
||||
@@ -677,10 +702,7 @@ static int do_option(int optc, const char *arg)
|
||||
//printf("compress_resources: %d\n", opt->win32_pe.compress_resources);
|
||||
break;
|
||||
case 633:
|
||||
opt->win32_pe.strip_loadconf = 1;
|
||||
if (mfx_optarg && strcmp(mfx_optarg,"0") == 0)
|
||||
opt->win32_pe.strip_loadconf = 0;
|
||||
//printf("strip_loadconf: %d\n", opt->win32_pe.strip_loadconf);
|
||||
// opt->win32_pe.strip_loadconf - OBSOLETE - IGNORED
|
||||
break;
|
||||
case 634:
|
||||
opt->win32_pe.strip_relocs = 1;
|
||||
@@ -688,6 +710,11 @@ static int do_option(int optc, const char *arg)
|
||||
opt->win32_pe.strip_relocs = 0;
|
||||
//printf("strip_relocs: %d\n", opt->win32_pe.strip_relocs);
|
||||
break;
|
||||
case 635:
|
||||
if (!mfx_optarg || !mfx_optarg[0])
|
||||
e_optarg(arg);
|
||||
opt->win32_pe.keep_resource = mfx_optarg;
|
||||
break;
|
||||
case 650:
|
||||
opt->atari_tos.split_segments = true;
|
||||
break;
|
||||
@@ -703,7 +730,25 @@ static int do_option(int optc, const char *arg)
|
||||
set_script_name(mfx_optarg,1);
|
||||
break;
|
||||
case 663:
|
||||
opt->o_unix.ptinterp = true;
|
||||
opt->o_unix.is_ptinterp = true;
|
||||
break;
|
||||
case 664:
|
||||
opt->o_unix.use_ptinterp = true;
|
||||
break;
|
||||
case 665:
|
||||
opt->o_unix.make_ptinterp = true;
|
||||
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:
|
||||
opt->ps1_exe.boot_only = true;
|
||||
@@ -715,6 +760,9 @@ static int do_option(int optc, const char *arg)
|
||||
case 672:
|
||||
opt->ps1_exe.do_8bit = true;
|
||||
break;
|
||||
case 673:
|
||||
opt->ps1_exe.do_8mb = false;
|
||||
break;
|
||||
|
||||
case '\0':
|
||||
return -1;
|
||||
@@ -750,7 +798,6 @@ static const struct mfx_option longopts[] =
|
||||
{"version", 0, 0, 'V'+256}, // display version number
|
||||
|
||||
// options
|
||||
{"debug", 0x10, 0, 'D'},
|
||||
{"force", 0, 0, 'f'}, // force overwrite of output files
|
||||
{"force-compress", 0, 0, 'f'}, // and compression of suspicious files
|
||||
{"info", 0, 0, 'i'}, // info mode
|
||||
@@ -766,6 +813,12 @@ static const struct mfx_option longopts[] =
|
||||
#endif
|
||||
{"verbose", 0, 0, 'v'}, // verbose mode
|
||||
|
||||
// debug options
|
||||
{"debug", 0x10, 0, 'D'},
|
||||
{"dump-stub-loader" ,0x31, 0, 544}, // for internal debugging
|
||||
{"fake-stub-version",0x31, 0, 542}, // for internal debugging
|
||||
{"fake-stub-year" ,0x31, 0, 543}, // for internal debugging
|
||||
|
||||
// backup options
|
||||
{"backup", 0, 0, 'k'},
|
||||
{"keep", 0, 0, 'k'},
|
||||
@@ -793,6 +846,7 @@ static const struct mfx_option longopts[] =
|
||||
{"nrv2b", 0x10, 0, 702}, // --nrv2b
|
||||
{"nrv2d", 0x10, 0, 704}, // --nrv2d
|
||||
{"nrv2e", 0x10, 0, 705}, // --nrv2e
|
||||
{"lzma", 0x10, 0, 721}, // --lzma
|
||||
// compression settings
|
||||
{"all-filters", 0x10, 0, 523},
|
||||
{"all-methods", 0x10, 0, 524},
|
||||
@@ -823,19 +877,27 @@ static const struct mfx_option longopts[] =
|
||||
#if 0
|
||||
{"script", 0x31, 0, 662}, // --script=
|
||||
#endif
|
||||
{"ptinterp", 0, 0, 663}, // linux/elf386 PT_INTERP program
|
||||
{"is_ptinterp", 0, 0, 663}, // linux/elf386 PT_INTERP program
|
||||
{"use_ptinterp", 0, 0, 664}, // linux/elf386 PT_INTERP program
|
||||
{"make_ptinterp", 0, 0, 665}, // linux/elf386 PT_INTERP program
|
||||
{"Linux", 0, 0, 666},
|
||||
{"FreeBSD", 0, 0, 667},
|
||||
{"NetBSD", 0, 0, 668},
|
||||
{"OpenBSD", 0, 0, 669},
|
||||
// watcom/le
|
||||
{"le", 0, 0, 620}, // produce LE output
|
||||
// win32/pe
|
||||
{"compress-exports", 2, 0, 630},
|
||||
{"compress-icons", 2, 0, 631},
|
||||
{"compress-resources", 2, 0, 632},
|
||||
{"strip-loadconf", 0x12, 0, 633},
|
||||
{"strip-loadconf", 0x12, 0, 633}, // OBSOLETE - IGNORED
|
||||
{"strip-relocs", 0x12, 0, 634},
|
||||
{"keep-resource", 0x31, 0, 635},
|
||||
// ps1/exe
|
||||
{"boot-only", 0x10, 0, 670},
|
||||
{"no-align", 0x10, 0, 671},
|
||||
{"8-bit", 0x10, 0, 672},
|
||||
{"8mb-ram", 0x10, 0, 673},
|
||||
|
||||
{ NULL, 0, NULL, 0 }
|
||||
};
|
||||
@@ -846,6 +908,7 @@ static const struct mfx_option longopts[] =
|
||||
prepare_shortopts(buf,"123456789hH?V",longopts),
|
||||
mfx_optind = 0;
|
||||
mfx_opterr = 1;
|
||||
opt->o_unix.osabi0 = Elf32_Ehdr::ELFOSABI_LINUX;
|
||||
while ((optc = mfx_getopt_long(argc, argv, buf, longopts, &longind)) >= 0)
|
||||
{
|
||||
if (do_option(optc, argv[mfx_optind-1]) != 0)
|
||||
@@ -912,8 +975,9 @@ static const struct mfx_option longopts[] =
|
||||
{"compress-exports", 2, 0, 630},
|
||||
{"compress-icons", 2, 0, 631},
|
||||
{"compress-resources", 2, 0, 632},
|
||||
{"strip-loadconf", 0x12, 0, 633},
|
||||
{"strip-loadconf", 0x12, 0, 633}, // OBSOLETE - IGNORED
|
||||
{"strip-relocs", 0x12, 0, 634},
|
||||
{"keep-resource", 0x31, 0, 635},
|
||||
|
||||
{ NULL, 0, NULL, 0 }
|
||||
};
|
||||
@@ -1028,6 +1092,27 @@ static void first_options(int argc, char **argv)
|
||||
// assert a sane architecture and compiler
|
||||
**************************************************************************/
|
||||
|
||||
template <class T> struct TestBELE {
|
||||
static int test(void)
|
||||
{
|
||||
T allbits; allbits = 0; allbits -= 1;
|
||||
T v1; v1 = 1; v1 *= 2; v1 -= 1;
|
||||
T v2; v2 = 1;
|
||||
assert( (v1 == v2)); assert(!(v1 != v2));
|
||||
assert( (v1 <= v2)); assert( (v1 >= v2));
|
||||
assert(!(v1 < v2)); assert(!(v1 > v2));
|
||||
v2 ^= allbits;
|
||||
assert(!(v1 == v2)); assert( (v1 != v2));
|
||||
assert( (v1 <= v2)); assert(!(v1 >= v2));
|
||||
assert( (v1 < v2)); assert(!(v1 > v2));
|
||||
v2 += 2;
|
||||
assert(v1 == 1); assert(v2 == 0);
|
||||
v1 <<= 1; v1 |= v2; v1 >>= 1; v2 &= v1; v2 /= v1; v2 *= v1;
|
||||
assert(v1 == 1); assert(v2 == 0);
|
||||
return (v1 ^ v2) == 1;
|
||||
}};
|
||||
|
||||
|
||||
#define ACC_WANT_ACC_CHK_CH 1
|
||||
#undef ACCCHK_ASSERT
|
||||
#include "miniacc.h"
|
||||
@@ -1051,40 +1136,67 @@ void upx_sanity_check(void)
|
||||
|
||||
COMPILE_TIME_ASSERT(sizeof(BE16) == 2)
|
||||
COMPILE_TIME_ASSERT(sizeof(BE32) == 4)
|
||||
COMPILE_TIME_ASSERT(sizeof(BE64) == 8)
|
||||
COMPILE_TIME_ASSERT(sizeof(LE16) == 2)
|
||||
COMPILE_TIME_ASSERT(sizeof(LE32) == 4)
|
||||
COMPILE_TIME_ASSERT(sizeof(LE64) == 8)
|
||||
|
||||
COMPILE_TIME_ASSERT_ALIGNOF(BE16, char)
|
||||
COMPILE_TIME_ASSERT_ALIGNOF(BE32, char)
|
||||
COMPILE_TIME_ASSERT_ALIGNOF(BE64, char)
|
||||
COMPILE_TIME_ASSERT_ALIGNOF(LE16, char)
|
||||
COMPILE_TIME_ASSERT_ALIGNOF(LE32, char)
|
||||
COMPILE_TIME_ASSERT_ALIGNOF(LE64, char)
|
||||
|
||||
COMPILE_TIME_ASSERT(sizeof(UPX_VERSION_STRING4) == 4 + 1)
|
||||
assert(strlen(UPX_VERSION_STRING4) == 4);
|
||||
assert(memcmp(UPX_VERSION_STRING4, UPX_VERSION_STRING, 4) == 0);
|
||||
COMPILE_TIME_ASSERT(sizeof(UPX_VERSION_YEAR) == 4 + 1)
|
||||
assert(strlen(UPX_VERSION_YEAR) == 4);
|
||||
assert(memcmp(UPX_VERSION_DATE_ISO, UPX_VERSION_YEAR, 4) == 0);
|
||||
assert(memcmp(UPX_VERSION_DATE + strlen(UPX_VERSION_DATE) - 4, UPX_VERSION_YEAR, 4) == 0);
|
||||
|
||||
#if 1
|
||||
const unsigned char dd[4] = { 0xff, 0xfe, 0xfd, 0xfc };
|
||||
assert(upx_adler32(dd, 4) == 0x09f003f7);
|
||||
assert(upx_adler32(dd, 4, 0) == 0x09ec03f6);
|
||||
assert(upx_adler32(dd, 4, 1) == 0x09f003f7);
|
||||
|
||||
assert(get_be16(dd) == 0xfffe);
|
||||
assert(get_be16_signed(dd) == -2);
|
||||
assert(get_be24(dd) == 0xfffefd);
|
||||
assert(get_be24_signed(dd) == -259);
|
||||
assert(get_be32(dd) == 0xfffefdfc);
|
||||
assert(get_be32_signed(dd) == -66052);
|
||||
assert(get_le16(dd) == 0xfeff);
|
||||
assert(get_le16_signed(dd) == -257);
|
||||
assert(get_le24(dd) == 0xfdfeff);
|
||||
assert(get_le24_signed(dd) == -131329);
|
||||
assert(get_le32(dd) == 0xfcfdfeff);
|
||||
assert(get_le32_signed(dd) == -50462977);
|
||||
assert(find_be16(dd, sizeof(dd), 0xfffe) == 0);
|
||||
assert(find_le16(dd, sizeof(dd), 0xfeff) == 0);
|
||||
assert(find_be32(dd, sizeof(dd), 0xfffefdfc) == 0);
|
||||
assert(find_le32(dd, sizeof(dd), 0xfcfdfeff) == 0);
|
||||
# if 1 && !defined(UPX_OFFICIAL_BUILD)
|
||||
assert(TestBELE<LE16>::test());
|
||||
assert(TestBELE<LE32>::test());
|
||||
assert(TestBELE<LE64>::test());
|
||||
assert(TestBELE<BE16>::test());
|
||||
assert(TestBELE<BE32>::test());
|
||||
assert(TestBELE<BE64>::test());
|
||||
# endif
|
||||
{
|
||||
static const unsigned char dd[32] = { 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 };
|
||||
const unsigned char *d;
|
||||
d = dd + 7;
|
||||
assert(upx_adler32(d, 4) == 0x09f003f7);
|
||||
assert(upx_adler32(d, 4, 0) == 0x09ec03f6);
|
||||
assert(upx_adler32(d, 4, 1) == 0x09f003f7);
|
||||
assert(get_be16(d) == 0xfffe);
|
||||
assert(get_be16_signed(d) == -2);
|
||||
assert(get_be24(d) == 0xfffefd);
|
||||
assert(get_be24_signed(d) == -259);
|
||||
assert(get_be32(d) == 0xfffefdfc);
|
||||
assert(get_be32_signed(d) == -66052);
|
||||
assert(get_le16(d) == 0xfeff);
|
||||
assert(get_le16_signed(d) == -257);
|
||||
assert(get_le24(d) == 0xfdfeff);
|
||||
assert(get_le24_signed(d) == -131329);
|
||||
assert(get_le32(d) == 0xfcfdfeff);
|
||||
assert(get_le32_signed(d) == -50462977);
|
||||
assert(find_be16(d, 2, 0xfffe) == 0);
|
||||
assert(find_le16(d, 2, 0xfeff) == 0);
|
||||
assert(find_be32(d, 4, 0xfffefdfc) == 0);
|
||||
assert(find_le32(d, 4, 0xfcfdfeff) == 0);
|
||||
d += 12;
|
||||
assert(get_be16_signed(d) == 32638);
|
||||
assert(get_be24_signed(d) == 8355453);
|
||||
assert(get_be32_signed(d) == 2138996092);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1104,11 +1216,6 @@ int __acc_cdecl_main main(int argc, char *argv[])
|
||||
#if 0 && defined(__DJGPP__)
|
||||
// LFN=n may cause problems with 2.03's _rename and mkdir under WinME
|
||||
putenv("LFN=y");
|
||||
#endif
|
||||
#if defined(__MINT__)
|
||||
__binmode(1);
|
||||
__set_binmode(stdout, 0);
|
||||
__set_binmode(stderr, 0);
|
||||
#endif
|
||||
acc_wildargv(&argc, &argv);
|
||||
|
||||
|
||||
+25
-10
@@ -2,8 +2,8 @@
|
||||
|
||||
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) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -60,6 +60,8 @@ static int mcheck_init()
|
||||
MemBuffer::MemBuffer() :
|
||||
b(NULL), b_size(0)
|
||||
{
|
||||
if (use_mcheck < 0)
|
||||
mcheck_init();
|
||||
}
|
||||
|
||||
MemBuffer::MemBuffer(unsigned size) :
|
||||
@@ -87,7 +89,7 @@ void MemBuffer::dealloc()
|
||||
set_be32(b + b_size, 0);
|
||||
set_be32(b + b_size + 4, 0);
|
||||
//
|
||||
::free(b - 8);
|
||||
::free(b - 16);
|
||||
}
|
||||
else
|
||||
::free(b);
|
||||
@@ -99,25 +101,38 @@ 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)extra >= 0);
|
||||
unsigned size = uncompressed_size + uncompressed_size/8 + 256 + extra;
|
||||
alloc(size);
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
void MemBuffer::allocForUncompression(unsigned uncompressed_size, unsigned extra)
|
||||
unsigned MemBuffer::getSizeForUncompression(unsigned uncompressed_size, unsigned extra)
|
||||
{
|
||||
assert((int)uncompressed_size > 0);
|
||||
assert((int)extra >= 0);
|
||||
unsigned size = uncompressed_size + extra;
|
||||
// size += 512; // 512 safety bytes
|
||||
// INFO: 3 bytes are the allowed overrun for the i386 asm_fast decompressors
|
||||
#if (ACC_ARCH_IA32)
|
||||
#if (ACC_ARCH_I386)
|
||||
size += 3;
|
||||
#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);
|
||||
}
|
||||
|
||||
@@ -173,7 +188,7 @@ void MemBuffer::alloc(unsigned size)
|
||||
assert(b_size == 0);
|
||||
//
|
||||
assert((int)size > 0);
|
||||
unsigned total = use_mcheck ? size + 16 : size;
|
||||
unsigned total = use_mcheck ? size + 32 : size;
|
||||
assert((int)total > 0);
|
||||
unsigned char *p = (unsigned char *) malloc(total);
|
||||
if (!p)
|
||||
@@ -185,7 +200,7 @@ void MemBuffer::alloc(unsigned size)
|
||||
b_size = size;
|
||||
if (use_mcheck)
|
||||
{
|
||||
b = p + 8;
|
||||
b = p + 16;
|
||||
// store magic constants to detect buffer overruns
|
||||
set_be32(b - 8, b_size);
|
||||
set_be32(b - 4, MAGIC1(b));
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
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) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -41,6 +41,9 @@ public:
|
||||
MemBuffer(unsigned size);
|
||||
~MemBuffer();
|
||||
|
||||
static unsigned getSizeForCompression(unsigned uncompressed_size, unsigned extra=0);
|
||||
static unsigned getSizeForUncompression(unsigned uncompressed_size, unsigned extra=0);
|
||||
|
||||
void alloc(unsigned size);
|
||||
void allocForCompression(unsigned uncompressed_size, unsigned extra=0);
|
||||
void allocForUncompression(unsigned uncompressed_size, unsigned extra=0);
|
||||
|
||||
+2815
-1115
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.
|
||||
|
||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2004 Laszlo Molnar
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -66,9 +66,9 @@ void printClearLine(FILE *f)
|
||||
static void pr_print(bool c, const char *msg)
|
||||
{
|
||||
if (c && !opt->to_stdout)
|
||||
con_fprintf(stderr,msg);
|
||||
con_fprintf(stderr, "%s", msg);
|
||||
else
|
||||
fprintf(stderr,msg);
|
||||
fprintf(stderr, "%s", msg);
|
||||
}
|
||||
|
||||
static void pr_error(const char *iname, const char *msg, bool is_warning)
|
||||
|
||||
+46
-15
@@ -2,8 +2,8 @@
|
||||
|
||||
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) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -47,15 +47,16 @@ struct options_t {
|
||||
|
||||
// compression options
|
||||
int method;
|
||||
int level; // compression level 1..10
|
||||
int filter; // preferred filter from Packer::getFilters()
|
||||
bool all_methods; // try all available compression methods ?
|
||||
bool all_filters; // try all available filters ?
|
||||
int level; // compression level 1..10
|
||||
int filter; // preferred filter from Packer::getFilters()
|
||||
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
|
||||
|
||||
// other options
|
||||
int backup;
|
||||
int console;
|
||||
int debug;
|
||||
int force;
|
||||
int info_mode;
|
||||
bool ignorewarn;
|
||||
@@ -66,6 +67,14 @@ struct options_t {
|
||||
int verbose;
|
||||
bool to_stdout;
|
||||
|
||||
// debug options
|
||||
struct {
|
||||
int debug_level;
|
||||
const char *dump_stub_loader;
|
||||
char fake_stub_version[4+1]; // for internal debugging
|
||||
char fake_stub_year[4+1]; // for internal debugging
|
||||
} debug;
|
||||
|
||||
// overlay handling
|
||||
enum {
|
||||
SKIP_OVERLAY = 0,
|
||||
@@ -75,15 +84,33 @@ struct options_t {
|
||||
int overlay;
|
||||
|
||||
// compression runtime parameters - see struct ucl_compress_config_t
|
||||
struct {
|
||||
upx_uint max_offset;
|
||||
upx_uint max_match;
|
||||
struct crp_lzma_t {
|
||||
int dummy;
|
||||
#if 0
|
||||
unsigned pos_bits; // pb
|
||||
unsigned lit_pos_bits; // lp
|
||||
unsigned lit_context_bits; // lc
|
||||
unsigned dict_size;
|
||||
unsigned mf_passes;
|
||||
#endif
|
||||
void reset() { memset(this, 0, sizeof(*this)); }
|
||||
};
|
||||
struct crp_ucl_t {
|
||||
unsigned max_offset;
|
||||
unsigned max_match;
|
||||
int s_level;
|
||||
int h_level;
|
||||
int p_level;
|
||||
int c_flags;
|
||||
upx_uint m_size;
|
||||
} crp;
|
||||
unsigned m_size;
|
||||
void reset() { memset(this, 0xff, sizeof(*this)); }
|
||||
};
|
||||
struct crp_t {
|
||||
crp_lzma_t crp_lzma;
|
||||
crp_ucl_t crp_ucl;
|
||||
void reset() { crp_lzma.reset(); crp_ucl.reset(); }
|
||||
};
|
||||
crp_t crp;
|
||||
|
||||
// CPU
|
||||
enum {
|
||||
@@ -112,11 +139,15 @@ struct options_t {
|
||||
bool boot_only;
|
||||
bool no_align;
|
||||
bool do_8bit;
|
||||
bool do_8mb;
|
||||
} ps1_exe;
|
||||
struct {
|
||||
unsigned blocksize;
|
||||
bool force_execve; // force the linux/386 execve format
|
||||
bool ptinterp; // is PT_INTERP, so don't adjust auxv_t
|
||||
bool is_ptinterp; // is PT_INTERP, so don't adjust auxv_t
|
||||
bool use_ptinterp; // use PT_INTERP /opt/upx/run
|
||||
bool make_ptinterp; // make PT_INTERP [ignore current file!]
|
||||
unsigned char osabi0; // replacement if 0==.e_ident[EI_OSABI]
|
||||
enum { SCRIPT_MAX = 32 };
|
||||
const char *script_name;
|
||||
} o_unix;
|
||||
@@ -128,12 +159,12 @@ struct options_t {
|
||||
int compress_icons;
|
||||
int compress_resources;
|
||||
signed char compress_rt[25]; // 25 == RT_LAST
|
||||
int strip_loadconf;
|
||||
int strip_relocs;
|
||||
const char *keep_resource;
|
||||
} win32_pe;
|
||||
};
|
||||
|
||||
extern struct options_t * volatile opt;
|
||||
extern struct options_t *opt;
|
||||
|
||||
|
||||
#endif /* already included */
|
||||
|
||||
+1135
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,72 @@
|
||||
/* p_armpe.h --
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
and/or modify them under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING.
|
||||
If not, write to the Free Software Foundation, Inc.,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
markus@oberhumer.com ml1050@users.sourceforge.net
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __UPX_P_ARMPE_H
|
||||
#define __UPX_P_ARMPE_H
|
||||
|
||||
/*************************************************************************
|
||||
// arm/pe
|
||||
**************************************************************************/
|
||||
|
||||
class PackArmPe : public PeFile
|
||||
{
|
||||
typedef PeFile super;
|
||||
|
||||
public:
|
||||
PackArmPe(InputFile *f);
|
||||
~PackArmPe();
|
||||
virtual int getFormat() const { return UPX_F_WINCE_ARM_PE; }
|
||||
virtual const char *getName() const { return "arm/pe"; }
|
||||
virtual const int *getCompressionMethods(int method, int level) const;
|
||||
virtual const int *getFilters() const;
|
||||
|
||||
virtual void pack(OutputFile *fo);
|
||||
|
||||
virtual bool canPack();
|
||||
virtual int canUnpack();
|
||||
|
||||
protected:
|
||||
virtual int buildLoader(const Filter *ft);
|
||||
virtual Linker* newLinker() const;
|
||||
|
||||
virtual unsigned processImports();
|
||||
virtual void processImports(unsigned, unsigned);
|
||||
virtual void rebuildImports(upx_byte *&);
|
||||
|
||||
virtual void processTls(Interval *);
|
||||
|
||||
bool use_thumb_stub;
|
||||
};
|
||||
|
||||
|
||||
#endif /* already included */
|
||||
|
||||
|
||||
/*
|
||||
vi:ts=4:et
|
||||
*/
|
||||
+27
-24
@@ -2,8 +2,8 @@
|
||||
|
||||
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) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -22,7 +22,7 @@
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
markus@oberhumer.com ml1050@cdata.tvnet.hu
|
||||
markus@oberhumer.com ml1050@users.sourceforge.net
|
||||
*/
|
||||
|
||||
|
||||
@@ -31,9 +31,10 @@
|
||||
#include "filter.h"
|
||||
#include "packer.h"
|
||||
#include "p_com.h"
|
||||
#include "linker.h"
|
||||
|
||||
static const
|
||||
#include "stub/l_com.h"
|
||||
#include "stub/i086-dos16.com.h"
|
||||
|
||||
//#define TESTING
|
||||
|
||||
@@ -98,7 +99,6 @@ void PackCom::patchLoader(OutputFile *fo,
|
||||
upx_byte *loader, int lsize,
|
||||
unsigned calls)
|
||||
{
|
||||
const int filter_id = ph.filter;
|
||||
const int e_len = getLoaderSectionStart("COMCUTPO");
|
||||
const int d_len = lsize - e_len;
|
||||
assert(e_len > 0 && e_len < 256);
|
||||
@@ -111,22 +111,18 @@ void PackCom::patchLoader(OutputFile *fo,
|
||||
if (upper_end + stacksize > 0xfffe)
|
||||
throwCantPack("file is too big for dos/com");
|
||||
|
||||
if (filter_id)
|
||||
{
|
||||
assert(calls > 0);
|
||||
patch_le16(loader,lsize,"CT",calls);
|
||||
}
|
||||
linker->defineSymbol("calltrick_calls", calls);
|
||||
linker->defineSymbol("sp_limit", upper_end + stacksize);
|
||||
linker->defineSymbol("bytes_to_copy", ph.c_len + lsize);
|
||||
linker->defineSymbol("copy_source", ph.c_len + lsize + 0x100);
|
||||
linker->defineSymbol("copy_destination", upper_end);
|
||||
linker->defineSymbol("COMCUTPO", ph.u_len + ph.overlap_overhead);
|
||||
|
||||
linker->relocate();
|
||||
loader = getLoader();
|
||||
|
||||
// some day we could use the relocation stuff for patchPackHeader too
|
||||
patchPackHeader(loader,e_len);
|
||||
|
||||
// NOTE: Depends on: decompr_start == cutpoint+1 !!!
|
||||
patch_le16(loader,e_len,"JM",upper_end - 0xff - d_len - getLoaderSection("UPX1HEAD"));
|
||||
loader[getLoaderSectionStart("COMSUBSI") - 1] = (upx_byte) -e_len;
|
||||
patch_le16(loader,e_len,"DI",upper_end);
|
||||
patch_le16(loader,e_len,"SI",ph.c_len + lsize + 0x100);
|
||||
patch_le16(loader,e_len,"CX",ph.c_len + lsize);
|
||||
patch_le16(loader,e_len,"SP",upper_end + stacksize);
|
||||
|
||||
// write loader + compressed file
|
||||
fo->write(loader,e_len); // entry
|
||||
fo->write(obuf,ph.c_len);
|
||||
@@ -142,15 +138,15 @@ void PackCom::patchLoader(OutputFile *fo,
|
||||
int PackCom::buildLoader(const Filter *ft)
|
||||
{
|
||||
initLoader(nrv2b_loader,sizeof(nrv2b_loader));
|
||||
addLoader("COMMAIN1""COMSUBSI",
|
||||
addLoader("COMMAIN1",
|
||||
ph.first_offset_found == 1 ? "COMSBBBP" : "",
|
||||
"COMPSHDI",
|
||||
ft->id ? "COMCALLT" : "",
|
||||
"COMMAIN2""UPX1HEAD""COMCUTPO""NRV2B160",
|
||||
"COMMAIN2,UPX1HEAD,COMCUTPO,NRV2B160",
|
||||
ft->id ? "NRVDDONE" : "NRVDRETU",
|
||||
"NRVDECO1",
|
||||
ph.max_offset_found <= 0xd00 ? "NRVLED00" : "NRVGTD00",
|
||||
"NRVDECO2""NRV2B169",
|
||||
"NRVDECO2",
|
||||
NULL
|
||||
);
|
||||
if (ft->id)
|
||||
@@ -158,6 +154,7 @@ int PackCom::buildLoader(const Filter *ft)
|
||||
assert(ft->calls > 0);
|
||||
addFilter16(ft->id);
|
||||
}
|
||||
freezeLoader();
|
||||
return getLoaderSize();
|
||||
}
|
||||
|
||||
@@ -170,7 +167,7 @@ void PackCom::addFilter16(int filter_id)
|
||||
if (filter_id % 3 == 0)
|
||||
addLoader("CALLTR16",
|
||||
filter_id < 4 ? "CT16SUB0" : "",
|
||||
filter_id < 4 ? "" : (opt->cpu == opt->CPU_8086 ? "CT16I086" : "CT16I286""CT16SUB0"),
|
||||
filter_id < 4 ? "" : (opt->cpu == opt->CPU_8086 ? "CT16I086" : "CT16I286,CT16SUB0"),
|
||||
"CALLTRI2",
|
||||
getFormat() == UPX_F_DOS_COM ? "CORETURN" : "",
|
||||
NULL
|
||||
@@ -180,7 +177,7 @@ void PackCom::addFilter16(int filter_id)
|
||||
"CALLTRI5",
|
||||
getFormat() == UPX_F_DOS_COM ? "CT16JEND" : "CT16JUL2",
|
||||
filter_id < 4 ? "CT16SUB1" : "",
|
||||
filter_id < 4 ? "" : (opt->cpu == opt->CPU_8086 ? "CT16I087" : "CT16I287""CT16SUB1"),
|
||||
filter_id < 4 ? "" : (opt->cpu == opt->CPU_8086 ? "CT16I087" : "CT16I287,CT16SUB1"),
|
||||
"CALLTRI6",
|
||||
NULL
|
||||
);
|
||||
@@ -270,6 +267,12 @@ void PackCom::unpack(OutputFile *fo)
|
||||
}
|
||||
|
||||
|
||||
Linker* PackCom::newLinker() const
|
||||
{
|
||||
return new ElfLinkerX86();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
vi:ts=4:et
|
||||
*/
|
||||
|
||||
+4
-3
@@ -2,8 +2,8 @@
|
||||
|
||||
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) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -22,7 +22,7 @@
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
markus@oberhumer.com ml1050@cdata.tvnet.hu
|
||||
markus@oberhumer.com ml1050@users.sourceforge.net
|
||||
*/
|
||||
|
||||
|
||||
@@ -53,6 +53,7 @@ public:
|
||||
|
||||
protected:
|
||||
virtual unsigned getCallTrickOffset() const { return 0x100; }
|
||||
virtual Linker* newLinker() const;
|
||||
|
||||
protected:
|
||||
virtual int buildLoader(const Filter *ft);
|
||||
|
||||
+70
-25
@@ -2,8 +2,8 @@
|
||||
|
||||
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) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -22,7 +22,7 @@
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
markus@oberhumer.com ml1050@cdata.tvnet.hu
|
||||
markus@oberhumer.com ml1050@users.sourceforge.net
|
||||
*/
|
||||
|
||||
|
||||
@@ -31,11 +31,12 @@
|
||||
#include "filter.h"
|
||||
#include "packer.h"
|
||||
#include "p_djgpp2.h"
|
||||
#include "linker.h"
|
||||
|
||||
static const
|
||||
#include "stub/l_djgpp2.h"
|
||||
#include "stub/i386-dos32.djgpp2.h"
|
||||
static const
|
||||
#include "stub/stubify.h"
|
||||
#include "stub/i386-dos32.djgpp2-stubify.h"
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
@@ -53,7 +54,7 @@ PackDjgpp2::PackDjgpp2(InputFile *f) :
|
||||
COMPILE_TIME_ASSERT(STUBIFY_STUB_ADLER32 == 0xbf689ba8);
|
||||
COMPILE_TIME_ASSERT(STUBIFY_STUB_CRC32 == 0x2ae982b2);
|
||||
//printf("0x%08x\n", upx_adler32(stubify_stub, sizeof(stubify_stub)));
|
||||
assert(upx_adler32(stubify_stub, sizeof(stubify_stub)) == STUBIFY_STUB_ADLER32);
|
||||
//assert(upx_adler32(stubify_stub, sizeof(stubify_stub)) == STUBIFY_STUB_ADLER32);
|
||||
}
|
||||
|
||||
|
||||
@@ -82,14 +83,22 @@ unsigned PackDjgpp2::findOverlapOverhead(const upx_bytep buf,
|
||||
}
|
||||
|
||||
|
||||
Linker* PackDjgpp2::newLinker() const
|
||||
{
|
||||
return new ElfLinkerX86;
|
||||
}
|
||||
|
||||
|
||||
int PackDjgpp2::buildLoader(const Filter *ft)
|
||||
{
|
||||
// prepare loader
|
||||
initLoader(nrv_loader, sizeof(nrv_loader));
|
||||
addLoader("IDENTSTR""DJ2MAIN1",
|
||||
addLoader("IDENTSTR,DJ2MAIN1",
|
||||
ft->id ? "DJCALLT1" : "",
|
||||
"DJ2MAIN2",
|
||||
getDecompressor(),
|
||||
ph.method == M_LZMA ? "LZMA_INIT_STACK" : "",
|
||||
getDecompressorSections(),
|
||||
ph.method == M_LZMA ? "LZMA_DONE_STACK" : "",
|
||||
"DJ2BSS00",
|
||||
NULL
|
||||
);
|
||||
@@ -99,7 +108,8 @@ int PackDjgpp2::buildLoader(const Filter *ft)
|
||||
addLoader("DJCALLT2", NULL);
|
||||
addFilter32(ft->id);
|
||||
}
|
||||
addLoader("DJRETURN+40DXXXXUPX1HEAD", NULL);
|
||||
addLoader("DJRETURN,+40C,UPX1HEAD", NULL);
|
||||
freezeLoader();
|
||||
return getLoaderSize();
|
||||
}
|
||||
|
||||
@@ -159,7 +169,7 @@ static void handle_allegropak(InputFile *fi, OutputFile *fo)
|
||||
if (memcmp(buf, "slh+", 4) != 0)
|
||||
return;
|
||||
pfsize = get_be32_signed(buf+4);
|
||||
if (pfsize <= 8 || pfsize >= fi->st.st_size)
|
||||
if (pfsize <= 8 || (off_t) pfsize >= (off_t) fi->st.st_size)
|
||||
return;
|
||||
fi->seek(-pfsize, SEEK_END);
|
||||
} catch (const IOException&) {
|
||||
@@ -225,6 +235,29 @@ void PackDjgpp2::stripDebug()
|
||||
}
|
||||
|
||||
|
||||
static bool defineFilterSymbols(Linker *linker, const Filter *ft)
|
||||
{
|
||||
if (ft->id == 0)
|
||||
return false;
|
||||
assert(ft->calls > 0);
|
||||
|
||||
linker->defineSymbol("filter_cto", ft->cto);
|
||||
linker->defineSymbol("filter_length",
|
||||
(ft->id & 0xf) % 3 == 0 ? ft->calls :
|
||||
ft->lastcall - ft->calls * 4);
|
||||
|
||||
#if 0
|
||||
if (0x80==(ft->id & 0xF0)) {
|
||||
int const mru = ph.n_mru ? 1+ ph.n_mru : 0;
|
||||
if (mru && mru!=256) {
|
||||
unsigned const is_pwr2 = (0==((mru -1) & mru));
|
||||
patch_le32(0x80 + (char *)loader, lsize - 0x80, "NMRU", mru - is_pwr2);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
@@ -290,33 +323,35 @@ void PackDjgpp2::pack(OutputFile *fo)
|
||||
ft.buf_len = usize - data->size;
|
||||
ft.addvalue = text->vaddr - hdrsize;
|
||||
// compress
|
||||
compressWithFilters(&ft, 512);
|
||||
upx_compress_config_t cconf; cconf.reset();
|
||||
// limit stack size needed for runtime decompression
|
||||
cconf.conf_lzma.max_num_probs = 1846 + (768 << 4); // ushort: ~28KB stack
|
||||
compressWithFilters(&ft, 512, 0, NULL, &cconf);
|
||||
|
||||
// patch coff header #2
|
||||
const unsigned lsize = getLoaderSize();
|
||||
assert(lsize % 4 == 0);
|
||||
text->size = lsize; // new size of .text
|
||||
data->size = ph.c_len; // new size of .data
|
||||
|
||||
if (bss->size < ph.overlap_overhead) // give it a .bss
|
||||
bss->size = ph.overlap_overhead;
|
||||
unsigned stack = 1024 + ph.overlap_overhead + getDecompressorWrkmemSize();
|
||||
stack = ALIGN_UP(stack, 16);
|
||||
if (bss->size < stack) // give it a .bss
|
||||
bss->size = stack;
|
||||
|
||||
text->scnptr = sizeof(coff_hdr);
|
||||
data->scnptr = text->scnptr + text->size;
|
||||
data->vaddr = bss->vaddr + ((data->scnptr + data->size) & 0x1ff) - data->size + ph.overlap_overhead - 0x200;
|
||||
coff_hdr.f_nscns = 3;
|
||||
|
||||
// prepare loader
|
||||
MemBuffer loader(lsize);
|
||||
memcpy(loader, getLoader(), lsize);
|
||||
|
||||
// patch loader
|
||||
patchPackHeader(loader, lsize);
|
||||
patch_le32(loader, lsize, "ENTR", coff_hdr.a_entry);
|
||||
patchFilter32(loader, lsize, &ft);
|
||||
patch_le32(loader, lsize, "BSSL", ph.overlap_overhead / 4);
|
||||
linker->defineSymbol("original_entry", coff_hdr.a_entry);
|
||||
linker->defineSymbol("length_of_bss", ph.overlap_overhead / 4);
|
||||
defineDecompressorSymbols();
|
||||
assert(bss->vaddr == ((size + 0x1ff) &~ 0x1ff) + (text->vaddr &~ 0x1ff));
|
||||
patch_le32(loader, lsize, "OUTP", text->vaddr - hdrsize);
|
||||
patch_le32(loader, lsize, "INPP", data->vaddr);
|
||||
linker->defineSymbol("stack_for_lzma", bss->vaddr + bss->size);
|
||||
linker->defineSymbol("start_of_uncompressed", text->vaddr - hdrsize);
|
||||
linker->defineSymbol("start_of_compressed", data->vaddr);
|
||||
defineFilterSymbols(linker, &ft);
|
||||
|
||||
// we should not overwrite our decompressor during unpacking
|
||||
// the original coff header (which is put just before the
|
||||
@@ -333,9 +368,19 @@ void PackDjgpp2::pack(OutputFile *fo)
|
||||
memcpy(obuf+data->size, "UPX", 3);
|
||||
data->size = ALIGN_UP(data->size, 4);
|
||||
|
||||
linker->defineSymbol("DJ2MAIN1", coff_hdr.a_entry);
|
||||
linker->relocate();
|
||||
|
||||
// prepare loader
|
||||
MemBuffer loader(lsize);
|
||||
memcpy(loader, getLoader(), lsize);
|
||||
patchPackHeader(loader, lsize);
|
||||
|
||||
// write coff header, loader and compressed file
|
||||
fo->write(&coff_hdr, sizeof(coff_hdr));
|
||||
fo->write(loader, lsize);
|
||||
if (opt->debug.dump_stub_loader)
|
||||
OutputFile::dump(opt->debug.dump_stub_loader, loader, lsize);
|
||||
fo->write(obuf, data->size);
|
||||
#if 0
|
||||
printf("%-13s: coff hdr : %8ld bytes\n", getName(), (long) sizeof(coff_hdr));
|
||||
@@ -367,7 +412,7 @@ int PackDjgpp2::canUnpack()
|
||||
if (is_dlm(fi, coff_offset))
|
||||
throwCantUnpack("can't handle DLM");
|
||||
fi->seek(coff_offset, SEEK_SET);
|
||||
return readPackHeader(1024) ? 1 : -1;
|
||||
return readPackHeader(4096) ? 1 : -1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
+4
-3
@@ -2,8 +2,8 @@
|
||||
|
||||
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) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -22,7 +22,7 @@
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
markus@oberhumer.com ml1050@cdata.tvnet.hu
|
||||
markus@oberhumer.com ml1050@users.sourceforge.net
|
||||
*/
|
||||
|
||||
|
||||
@@ -60,6 +60,7 @@ protected:
|
||||
unsigned range = 0,
|
||||
unsigned upper_limit = ~0u) const;
|
||||
virtual int buildLoader(const Filter *ft);
|
||||
virtual Linker* newLinker() const;
|
||||
|
||||
long coff_offset;
|
||||
|
||||
|
||||
+327
-78
@@ -2,8 +2,8 @@
|
||||
|
||||
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) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -22,7 +22,7 @@
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
markus@oberhumer.com ml1050@cdata.tvnet.hu
|
||||
markus@oberhumer.com ml1050@users.sourceforge.net
|
||||
*/
|
||||
|
||||
|
||||
@@ -34,99 +34,159 @@
|
||||
// Some ELF type definitinons
|
||||
**************************************************************************/
|
||||
|
||||
namespace N_Elf {
|
||||
|
||||
// The ELF file header. This appears at the start of every ELF file.
|
||||
struct Elf_LE32_Ehdr
|
||||
template <class Word, class Addr, class Off, class Half>
|
||||
struct Ehdr
|
||||
{
|
||||
unsigned char e_ident[16]; /* Magic number and other info */
|
||||
LE16 e_type; /* Object file type */
|
||||
LE16 e_machine; /* Architecture */
|
||||
LE32 e_version; /* Object file version */
|
||||
LE32 e_entry; /* Entry point virtual address */
|
||||
LE32 e_phoff; /* Program header table file offset */
|
||||
LE32 e_shoff; /* Section header table file offset */
|
||||
LE32 e_flags; /* Processor-specific flags */
|
||||
LE16 e_ehsize; /* ELF header size in bytes */
|
||||
LE16 e_phentsize; /* Program header table entry size */
|
||||
LE16 e_phnum; /* Program header table entry count */
|
||||
LE16 e_shentsize; /* Section header table entry size */
|
||||
LE16 e_shnum; /* Section header table entry count */
|
||||
LE16 e_shstrndx; /* Section header string table index */
|
||||
Half e_type; /* Object file type */
|
||||
Half e_machine; /* Architecture */
|
||||
Word e_version; /* Object file version */
|
||||
Addr e_entry; /* Entry point virtual address */
|
||||
Off e_phoff; /* Program header table file offset */
|
||||
Off e_shoff; /* Section header table file offset */
|
||||
Word e_flags; /* Processor-specific flags */
|
||||
Half e_ehsize; /* ELF header size in bytes */
|
||||
Half e_phentsize; /* Program header table entry size */
|
||||
Half e_phnum; /* Program header table entry count */
|
||||
Half e_shentsize; /* Section header table entry size */
|
||||
Half e_shnum; /* Section header table entry count */
|
||||
Half e_shstrndx; /* Section header string table index */
|
||||
|
||||
// Values for e_type
|
||||
enum {
|
||||
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_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_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_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>
|
||||
struct Dyn
|
||||
{
|
||||
Word d_tag;
|
||||
Addr d_val;
|
||||
|
||||
enum { // d_tag
|
||||
DT_NULL = 0, /* End flag */
|
||||
DT_NEEDED = 1, /* Name of needed library */
|
||||
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 N_Elf
|
||||
|
||||
|
||||
namespace N_Elf32 {
|
||||
|
||||
// Program segment header.
|
||||
struct Elf_LE32_Phdr
|
||||
template <class Word, class Addr, class Off>
|
||||
struct Phdr
|
||||
{
|
||||
LE32 p_type; /* Segment type */
|
||||
LE32 p_offset; /* Segment file offset */
|
||||
LE32 p_vaddr; /* Segment virtual address */
|
||||
LE32 p_paddr; /* Segment physical address */
|
||||
LE32 p_filesz; /* Segment size in file */
|
||||
LE32 p_memsz; /* Segment size in memory */
|
||||
LE32 p_flags; /* Segment flags */
|
||||
LE32 p_align; /* Segment alignment */
|
||||
Word p_type; /* Segment type */
|
||||
Off p_offset; /* Segment file offset */
|
||||
Addr p_vaddr; /* Segment virtual address */
|
||||
Addr p_paddr; /* Segment physical address */
|
||||
Word p_filesz; /* Segment size in file */
|
||||
Word p_memsz; /* Segment size in memory */
|
||||
Word p_flags; /* Segment flags */
|
||||
Word p_align; /* Segment alignment */
|
||||
|
||||
// Values for p_type
|
||||
enum {
|
||||
PT_LOAD = 1, /* Loadable program segment */
|
||||
PT_DYNAMIC = 2, /* Dynamic linking information */
|
||||
PT_PHDR = 6 /* Entry for header table itself */
|
||||
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 */
|
||||
};
|
||||
|
||||
// Values for p_flags
|
||||
enum { PF_X = (1 << 0) }; /* Segment is executable */
|
||||
enum { PF_W = (1 << 1) }; /* Segment is writable */
|
||||
enum { PF_R = (1 << 2) }; /* Segment is readable */
|
||||
enum { // p_flags
|
||||
PF_X = 1, /* Segment is executable */
|
||||
PF_W = 2, /* Segment is writable */
|
||||
PF_R = 4, /* Segment is readable */
|
||||
};
|
||||
}
|
||||
__attribute_packed;
|
||||
|
||||
|
||||
struct Elf_LE32_Shdr
|
||||
template <class Word, class Addr, class Off>
|
||||
struct Shdr
|
||||
{
|
||||
LE32 sh_name; /* Section name (string tbl index) */
|
||||
LE32 sh_type; /* Section type */
|
||||
LE32 sh_flags; /* Section flags */
|
||||
LE32 sh_addr; /* Section virtual addr at execution */
|
||||
LE32 sh_offset; /* Section file offset */
|
||||
LE32 sh_size; /* Section size in bytes */
|
||||
LE32 sh_link; /* Link to another section */
|
||||
LE32 sh_info; /* Additional section information */
|
||||
LE32 sh_addralign; /* Section alignment */
|
||||
LE32 sh_entsize; /* Entry size if section holds table */
|
||||
Word sh_name; /* Section name (string tbl index) */
|
||||
Word sh_type; /* Section type */
|
||||
Word sh_flags; /* Section flags */
|
||||
Addr sh_addr; /* Section virtual addr at execution */
|
||||
Off sh_offset; /* Section file offset */
|
||||
Word sh_size; /* Section size in bytes */
|
||||
Word sh_link; /* Link to another section */
|
||||
Word sh_info; /* Additional section information */
|
||||
Word sh_addralign; /* Section alignment */
|
||||
Word sh_entsize; /* Entry size if section holds table */
|
||||
|
||||
enum { // values for 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 */
|
||||
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_GROUP = 17, /* Section group */
|
||||
SHT_SYMTAB_SHNDX = 18, /* Extended section indeces */
|
||||
SHT_NUM = 19 /* Number of defined types. */
|
||||
SHT_GNU_LIBLIST = 0x6ffffff7, /* Prelink library list */
|
||||
};
|
||||
|
||||
enum { // values for sh_flags
|
||||
enum { // sh_flags
|
||||
SHF_WRITE = (1 << 0), /* Writable */
|
||||
SHF_ALLOC = (1 << 1), /* Occupies memory during execution */
|
||||
SHF_EXECINSTR = (1 << 2), /* Executable */
|
||||
@@ -138,20 +198,209 @@ struct Elf_LE32_Shdr
|
||||
}
|
||||
__attribute_packed;
|
||||
|
||||
struct Elf_LE32_Dyn
|
||||
template <class TT16, class TT32>
|
||||
struct Sym
|
||||
{
|
||||
LE32 d_tag;
|
||||
LE32 d_val;
|
||||
TT32 st_name; /* symbol name (index into string table) */
|
||||
TT32 st_value; /* symbol value */
|
||||
TT32 st_size; /* symbol size */
|
||||
unsigned char st_info; /* symbol type and binding */
|
||||
unsigned char st_other; /* symbol visibility */
|
||||
TT16 st_shndx; /* section index */
|
||||
|
||||
enum { // tags
|
||||
DT_NULL = 0, /* End flag */
|
||||
DT_NEEDED = 1, /* Name of needed library */
|
||||
DT_STRTAB = 5, /* String table */
|
||||
DT_STRSZ = 10 /* Sizeof string table */
|
||||
unsigned int st_bind(unsigned int x) const { return 0xf & (x>>4); }
|
||||
unsigned int st_type(unsigned int x) const { return 0xf & x ; }
|
||||
unsigned char St_info(unsigned bind, unsigned type) const { return (bind<<4) + (0xf & type); }
|
||||
|
||||
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 */
|
||||
};
|
||||
}
|
||||
__attribute_packed;
|
||||
|
||||
} // namespace N_Elf32
|
||||
|
||||
|
||||
namespace N_Elf64 {
|
||||
|
||||
// Program segment header.
|
||||
template <class Word, class Xword, class Addr, class Off>
|
||||
struct Phdr
|
||||
{
|
||||
Word p_type; /* Segment type */
|
||||
Word p_flags; /* Segment flags */
|
||||
Off p_offset; /* Segment file offset */
|
||||
Addr p_vaddr; /* Segment virtual address */
|
||||
Addr p_paddr; /* Segment physical address */
|
||||
Xword p_filesz; /* Segment size in file */
|
||||
Xword p_memsz; /* Segment size in memory */
|
||||
Xword p_align; /* Segment alignment */
|
||||
|
||||
enum { // p_type
|
||||
PT_LOAD = 1, /* Loadable program segment */
|
||||
PT_DYNAMIC = 2, /* Dynamic linking information */
|
||||
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>
|
||||
struct Shdr
|
||||
{
|
||||
Word sh_name; /* Section name (string tbl index) */
|
||||
Word sh_type; /* Section type */
|
||||
Xword sh_flags; /* Section flags */
|
||||
Addr sh_addr; /* Section virtual addr at execution */
|
||||
Off sh_offset; /* Section file offset */
|
||||
Xword sh_size; /* Section size in bytes */
|
||||
Word sh_link; /* Link to another section */
|
||||
Word sh_info; /* Additional section information */
|
||||
Xword sh_addralign; /* Section alignment */
|
||||
Xword sh_entsize; /* Entry size if section holds table */
|
||||
|
||||
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 */
|
||||
};
|
||||
}
|
||||
__attribute_packed;
|
||||
|
||||
} // namespace N_Elf64
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// now for the actual types
|
||||
**************************************************************************/
|
||||
|
||||
#define P N_BELE_CTP::HostPolicy
|
||||
typedef N_Elf ::Ehdr<P::U32,P::U32,P::U32,P::U16> Elf32_Ehdr;
|
||||
typedef N_Elf32::Phdr<P::U32,P::U32,P::U32> Elf32_Phdr;
|
||||
typedef N_Elf32::Shdr<P::U32,P::U32,P::U32> Elf32_Shdr;
|
||||
typedef N_Elf ::Dyn <P::U32,P::U32> Elf32_Dyn;
|
||||
typedef N_Elf32::Sym <P::U16,P::U32> Elf32_Sym;
|
||||
#undef P
|
||||
|
||||
#define P N_BELE_CTP::BEPolicy
|
||||
typedef N_Elf ::Ehdr<P::U32,P::U32,P::U32,P::U16> Elf_BE32_Ehdr;
|
||||
typedef N_Elf32::Phdr<P::U32,P::U32,P::U32> Elf_BE32_Phdr;
|
||||
typedef N_Elf32::Shdr<P::U32,P::U32,P::U32> Elf_BE32_Shdr;
|
||||
typedef N_Elf ::Dyn <P::U32,P::U32> Elf_BE32_Dyn;
|
||||
typedef N_Elf32::Sym <P::U16,P::U32> Elf_BE32_Sym;
|
||||
#undef P
|
||||
|
||||
#define P N_BELE_CTP::LEPolicy
|
||||
typedef N_Elf ::Ehdr<P::U32,P::U32,P::U32,P::U16> Elf_LE32_Ehdr;
|
||||
typedef N_Elf32::Phdr<P::U32,P::U32,P::U32> Elf_LE32_Phdr;
|
||||
typedef N_Elf32::Shdr<P::U32,P::U32,P::U32> Elf_LE32_Shdr;
|
||||
typedef N_Elf ::Dyn <P::U32,P::U32> Elf_LE32_Dyn;
|
||||
typedef N_Elf32::Sym <P::U16,P::U32> Elf_LE32_Sym;
|
||||
#undef P
|
||||
|
||||
#define P N_BELE_CTP::HostPolicy
|
||||
typedef N_Elf ::Ehdr<P::U32,P::U64,P::U64,P::U16> Elf64_Ehdr;
|
||||
typedef N_Elf64::Phdr<P::U32,P::U64,P::U64,P::U64> Elf64_Phdr;
|
||||
typedef N_Elf64::Shdr<P::U32,P::U64,P::U64,P::U64> Elf64_Shdr;
|
||||
typedef N_Elf ::Dyn <P::U64,P::U64> Elf64_Dyn;
|
||||
#undef P
|
||||
|
||||
#define P N_BELE_CTP::BEPolicy
|
||||
typedef N_Elf ::Ehdr<P::U32,P::U64,P::U64,P::U16> Elf_BE64_Ehdr;
|
||||
typedef N_Elf64::Phdr<P::U32,P::U64,P::U64,P::U64> Elf_BE64_Phdr;
|
||||
typedef N_Elf64::Shdr<P::U32,P::U64,P::U64,P::U64> Elf_BE64_Shdr;
|
||||
typedef N_Elf ::Dyn <P::U64,P::U64> Elf_BE64_Dyn;
|
||||
#undef P
|
||||
|
||||
#define P N_BELE_CTP::LEPolicy
|
||||
typedef N_Elf ::Ehdr<P::U32,P::U64,P::U64,P::U16> Elf_LE64_Ehdr;
|
||||
typedef N_Elf64::Phdr<P::U32,P::U64,P::U64,P::U64> Elf_LE64_Phdr;
|
||||
typedef N_Elf64::Shdr<P::U32,P::U64,P::U64,P::U64> Elf_LE64_Shdr;
|
||||
typedef N_Elf ::Dyn <P::U64,P::U64> Elf_LE64_Dyn;
|
||||
#undef P
|
||||
|
||||
|
||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf32_Ehdr) == 52)
|
||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf32_Phdr) == 32)
|
||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf32_Shdr) == 40)
|
||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf32_Dyn) == 8)
|
||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf32_Sym) == 16)
|
||||
|
||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_BE32_Ehdr) == 52)
|
||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_BE32_Phdr) == 32)
|
||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_BE32_Shdr) == 40)
|
||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_BE32_Dyn) == 8)
|
||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_BE32_Sym) == 16)
|
||||
|
||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_LE32_Ehdr) == 52)
|
||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_LE32_Phdr) == 32)
|
||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_LE32_Shdr) == 40)
|
||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_LE32_Dyn) == 8)
|
||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_LE32_Sym) == 16)
|
||||
|
||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf64_Ehdr) == 64)
|
||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf64_Phdr) == 56)
|
||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf64_Shdr) == 64)
|
||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf64_Dyn) == 16)
|
||||
|
||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_BE64_Ehdr) == 64)
|
||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_BE64_Phdr) == 56)
|
||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_BE64_Shdr) == 64)
|
||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_BE64_Dyn) == 16)
|
||||
|
||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_LE64_Ehdr) == 64)
|
||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_LE64_Phdr) == 56)
|
||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_LE64_Shdr) == 64)
|
||||
ACC_COMPILE_TIME_ASSERT_HEADER(sizeof(Elf_LE64_Dyn) == 16)
|
||||
|
||||
|
||||
#endif /* already included */
|
||||
|
||||
|
||||
|
||||
+6
-4
@@ -2,8 +2,8 @@
|
||||
|
||||
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) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -22,7 +22,7 @@
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
markus@oberhumer.com ml1050@cdata.tvnet.hu
|
||||
markus@oberhumer.com ml1050@users.sourceforge.net
|
||||
*/
|
||||
|
||||
|
||||
@@ -100,6 +100,7 @@ int PackElks8086::buildLoader(const Filter *ft)
|
||||
initLoader(nrv_loader, sizeof(nrv_loader));
|
||||
// FIXME
|
||||
UNUSED(ft);
|
||||
freezeLoader();
|
||||
return getLoaderSize();
|
||||
}
|
||||
|
||||
@@ -122,7 +123,8 @@ void PackElks8086::pack(OutputFile *fo)
|
||||
patchPackHeader(loader, lsize);
|
||||
#if 0
|
||||
// FIXME
|
||||
patchFilter32(loader, lsize, &ft);
|
||||
defineFilterSymbols();
|
||||
defineDecompressorSymbols();
|
||||
patch_le32(loader, lsize, "ESI1", zimage_offset + lsize);
|
||||
patch_le32(loader, lsize, "KEIP", kernel_entry);
|
||||
patch_le32(loader, lsize, "STAK", stack_during_uncompression);
|
||||
|
||||
+62
-43
@@ -2,8 +2,8 @@
|
||||
|
||||
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) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -22,7 +22,7 @@
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
markus@oberhumer.com ml1050@cdata.tvnet.hu
|
||||
markus@oberhumer.com ml1050@users.sourceforge.net
|
||||
*/
|
||||
|
||||
|
||||
@@ -31,9 +31,10 @@
|
||||
#include "filter.h"
|
||||
#include "packer.h"
|
||||
#include "p_exe.h"
|
||||
#include "linker.h"
|
||||
|
||||
static const
|
||||
#include "stub/l_exe.h"
|
||||
#include "stub/i086-dos16.exe.h"
|
||||
|
||||
#define RSFCRI 4096 // Reserved Space For Compressed Relocation Info
|
||||
#define MAXMATCH 0x2000
|
||||
@@ -80,7 +81,6 @@ int PackExe::fillExeHeader(struct exe_header_t *eh) const
|
||||
memset(&oh,0,sizeof(oh));
|
||||
oh.ident = 'M' + 'Z' * 256;
|
||||
oh.headsize16 = 2;
|
||||
oh.ip = 0;
|
||||
|
||||
oh.sp = ih.sp > 0x200 ? (unsigned) ih.sp : 0x200;
|
||||
|
||||
@@ -108,9 +108,13 @@ int PackExe::buildLoader(const Filter *)
|
||||
|
||||
// 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",
|
||||
"EXEMAIN4,+G5DXXXX,UPX1HEAD,EXECUTPO",
|
||||
NULL
|
||||
);
|
||||
if (ph.method == M_NRV2B_8)
|
||||
@@ -122,7 +126,7 @@ int PackExe::buildLoader(const Filter *)
|
||||
opt->cpu == opt->CPU_8086 ? "N2BX8602" : "N2B28602",
|
||||
"NRV2BEX3",
|
||||
ph.c_len > 0xffff ? "N2B64K02" : "",
|
||||
"NRV2BEX9""NRV2B16E",
|
||||
"NRV2BEX9",
|
||||
NULL
|
||||
);
|
||||
else if (ph.method == M_NRV2D_8)
|
||||
@@ -134,7 +138,7 @@ int PackExe::buildLoader(const Filter *)
|
||||
opt->cpu == opt->CPU_8086 ? "N2DX8602" : "N2D28602",
|
||||
"NRV2DEX3",
|
||||
ph.c_len > 0xffff ? "N2D64K02" : "",
|
||||
"NRV2DEX9""NRV2D16E",
|
||||
"NRV2DEX9",
|
||||
NULL
|
||||
);
|
||||
else if (ph.method == M_NRV2E_8)
|
||||
@@ -146,7 +150,7 @@ int PackExe::buildLoader(const Filter *)
|
||||
opt->cpu == opt->CPU_8086 ? "N2EX8602" : "N2E28602",
|
||||
"NRV2EEX3",
|
||||
ph.c_len > 0xffff ? "N2E64K02" : "",
|
||||
"NRV2EEX9""NRV2E16E",
|
||||
"NRV2EEX9",
|
||||
NULL
|
||||
);
|
||||
else
|
||||
@@ -162,6 +166,7 @@ int PackExe::buildLoader(const Filter *)
|
||||
NULL
|
||||
);
|
||||
addLoader("EXEMAIN8",
|
||||
device_driver ? "DEVICEEND" : "",
|
||||
(flag & SS) ? "EXESTACK" : "",
|
||||
(flag & SP) ? "EXESTASP" : "",
|
||||
(flag & USEJUMP) ? "EXEJUMPF" : "",
|
||||
@@ -172,6 +177,7 @@ int PackExe::buildLoader(const Filter *)
|
||||
"EXERETIP",
|
||||
NULL
|
||||
);
|
||||
freezeLoader();
|
||||
return getLoaderSize();
|
||||
}
|
||||
|
||||
@@ -293,7 +299,9 @@ unsigned optimize_relocs(upx_byte *b, const unsigned size,
|
||||
{
|
||||
addr = get_le32(relocs+4*i);
|
||||
//printf ("%x\n",es*16+di);
|
||||
if (addr - es*16 > 0xfffe)
|
||||
if ((addr - es*16 > 0xfffe)
|
||||
|| (i == nrelocs - 1 && addr - es * 16 > 0xff00)
|
||||
)
|
||||
{
|
||||
// segment change
|
||||
t = 1+(0xffff-di)/254;
|
||||
@@ -365,6 +373,8 @@ void PackExe::pack(OutputFile *fo)
|
||||
|
||||
checkAlreadyPacked(ibuf, UPX_MIN(ih_imagesize, 127u));
|
||||
|
||||
device_driver = get_le32(ibuf) == 0xffffffffu;
|
||||
|
||||
// relocations
|
||||
has_9a = false;
|
||||
upx_byte *w = ibuf + ih_imagesize;
|
||||
@@ -403,13 +413,15 @@ void PackExe::pack(OutputFile *fo)
|
||||
ph.u_len = ih_imagesize + relocsize;
|
||||
// prepare filter
|
||||
Filter ft(ph.level);
|
||||
// compress
|
||||
compressWithFilters(&ft, 32, 0, NULL, 0, MAXMATCH);
|
||||
// compress (max_match = 8192)
|
||||
upx_compress_config_t cconf; cconf.reset();
|
||||
cconf.conf_ucl.max_match = MAXMATCH;
|
||||
compressWithFilters(&ft, 32, 0, NULL, &cconf);
|
||||
if (ph.max_run_found + ph.max_match_found > 0x8000)
|
||||
throwCantPack("decompressor limit exceeded, send a bugreport");
|
||||
|
||||
#ifdef TESTING
|
||||
if (opt->debug)
|
||||
if (opt->debug.debug_level)
|
||||
{
|
||||
printf("image+relocs %d -> %d\n",ih_imagesize+relocsize,ph.c_len);
|
||||
printf("offsets: %d - %d\nmatches: %d - %d\nruns: %d - %d\n",
|
||||
@@ -472,60 +484,61 @@ void PackExe::pack(OutputFile *fo)
|
||||
}
|
||||
extra_info[eisize++] = (unsigned char) flag;
|
||||
|
||||
linker->defineSymbol("original_cs", ih.cs);
|
||||
linker->defineSymbol("original_ip", ih.ip);
|
||||
linker->defineSymbol("original_sp", ih.sp);
|
||||
linker->defineSymbol("original_ss", ih.ss);
|
||||
linker->defineSymbol("reloc_size",
|
||||
(ph.u_len <= DI_LIMIT || (ph.u_len & 0x7fff)
|
||||
>= relocsize ? 0 : MAXRELOCS) - relocsize);
|
||||
linker->defineSymbol("bx_magic", 0x7FFF + 0x10 * ((packedsize & 15) + 1));
|
||||
linker->defineSymbol("decompressor_entry", (packedsize & 15) + 1);
|
||||
|
||||
// patch loader
|
||||
if (flag & USEJUMP)
|
||||
{
|
||||
// I use a relocation entry to set the original cs
|
||||
unsigned n = find_le32(loader,lsize,get_le32("IPCS"));
|
||||
patch_le32(loader,lsize,get_le32("IPCS"), ih.cs*0x10000 + ih.ip);
|
||||
unsigned n = getLoaderSectionStart("EXEJUMPF") + 1;
|
||||
n += packedsize + 2;
|
||||
oh.relocs = 1;
|
||||
oh.firstreloc = (n&0xf) + ((n>>4)<<16);
|
||||
oh.firstreloc = (n & 0xf) + ((n >> 4) << 16);
|
||||
}
|
||||
else
|
||||
{
|
||||
patch_le16(loader,lsize,"IP",ih.ip);
|
||||
if (ih.cs)
|
||||
patch_le16(loader,lsize,"CS",ih.cs);
|
||||
oh.relocs = 0;
|
||||
oh.firstreloc = ih.cs*0x10000 + ih.ip;
|
||||
oh.firstreloc = ih.cs * 0x10000 + ih.ip;
|
||||
}
|
||||
|
||||
// g++ 3.1 does not like the following line...
|
||||
// oh.relocoffs = offsetof(exe_header_t, firstreloc);
|
||||
oh.relocoffs = ptr_diff(&oh.firstreloc, &oh);
|
||||
|
||||
if (flag & SP)
|
||||
patch_le16(loader,lsize,"SP",ih.sp);
|
||||
if (flag & SS)
|
||||
patch_le16(loader,lsize,"SS",ih.ss);
|
||||
if (relocsize)
|
||||
patch_le16(loader,lsize,"RS",(ph.u_len <= DI_LIMIT || (ph.u_len & 0x7fff) >= relocsize ? 0 : MAXRELOCS) - relocsize);
|
||||
linker->defineSymbol("destination_segment", oh.ss - ph.c_len / 16 - e_len / 16);
|
||||
linker->defineSymbol("source_segment", e_len / 16 + (copysize - firstcopy) / 16);
|
||||
linker->defineSymbol("copy_offset", firstcopy - 2);
|
||||
linker->defineSymbol("words_to_copy",firstcopy / 2);
|
||||
|
||||
patchPackHeader(loader,e_len);
|
||||
|
||||
patch_le16(loader,e_len,"BX",0x800F + 0x10*((packedsize&15)+1) - 0x10);
|
||||
patch_le16(loader,e_len,"BP",(packedsize&15)+1);
|
||||
|
||||
unsigned destpara = oh.ss - ph.c_len/16;
|
||||
patch_le16(loader,e_len,"ES",destpara-e_len/16);
|
||||
patch_le16(loader,e_len,"DS",e_len/16+(copysize-firstcopy)/16);
|
||||
patch_le16(loader,e_len,"SI",firstcopy-2);
|
||||
patch_le16(loader,e_len,"CX",firstcopy/2);
|
||||
|
||||
// finish --stub support
|
||||
//if (ih.relocoffs >= 0x40 && memcmp(&ih.relocoffs,">TIPPACH",8))
|
||||
// throwCantPack("FIXME");
|
||||
linker->defineSymbol("exe_stack_sp", oh.sp);
|
||||
linker->defineSymbol("exe_stack_ss", oh.ss);
|
||||
linker->defineSymbol("interrupt", get_le16(ibuf + 8));
|
||||
linker->defineSymbol("attribute", get_le16(ibuf + 4));
|
||||
linker->defineSymbol("orig_strategy", get_le16(ibuf + 6));
|
||||
|
||||
const unsigned outputlen = sizeof(oh)+lsize+packedsize+eisize;
|
||||
oh.m512 = outputlen & 511;
|
||||
oh.p512 = (outputlen + 511) >> 9;
|
||||
|
||||
//fprintf(stderr,"\ne_len=%x d_len=%x clen=%x oo=%x ulen=%x destp=%x copys=%x images=%x",e_len,d_len,packedsize,ph.overlap_overhead,ph.u_len,destpara,copysize,ih_imagesize);
|
||||
oh.ip = device_driver ? getLoaderSection("EXEENTRY") - 2 : 0;
|
||||
|
||||
linker->relocate();
|
||||
memcpy(loader, getLoader(), lsize);
|
||||
patchPackHeader(loader,e_len);
|
||||
|
||||
//fprintf(stderr,"\ne_len=%x d_len=%x c_len=%x oo=%x ulen=%x destp=%x copys=%x images=%x",e_len,d_len,packedsize,ph.overlap_overhead,ph.u_len,destpara,copysize,ih_imagesize);
|
||||
|
||||
// write header + write loader + compressed file
|
||||
#ifdef TESTING
|
||||
if (opt->debug)
|
||||
if (opt->debug.debug_level)
|
||||
printf("\n%d %d %d %d\n",(int)sizeof(oh),e_len,packedsize,d_len);
|
||||
#endif
|
||||
fo->write(&oh,sizeof(oh));
|
||||
@@ -565,7 +578,7 @@ int PackExe::canUnpack()
|
||||
return false;
|
||||
const off_t off = ih.headsize16 * 16;
|
||||
fi->seek(off, SEEK_SET);
|
||||
bool b = readPackHeader(128);
|
||||
bool b = readPackHeader(256);
|
||||
return b && (off + (off_t) ph.c_len <= file_size);
|
||||
}
|
||||
|
||||
@@ -695,6 +708,12 @@ void PackExe::unpack(OutputFile *fo)
|
||||
}
|
||||
|
||||
|
||||
Linker* PackExe::newLinker() const
|
||||
{
|
||||
return new ElfLinkerX86();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
vi:ts=4:et
|
||||
*/
|
||||
|
||||
+5
-3
@@ -2,8 +2,8 @@
|
||||
|
||||
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) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -22,7 +22,7 @@
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
markus@oberhumer.com ml1050@cdata.tvnet.hu
|
||||
markus@oberhumer.com ml1050@users.sourceforge.net
|
||||
*/
|
||||
|
||||
|
||||
@@ -69,6 +69,7 @@ protected:
|
||||
|
||||
virtual int fillExeHeader(struct exe_header_t *) const;
|
||||
virtual int buildLoader(const Filter *ft);
|
||||
virtual Linker* newLinker() const;
|
||||
|
||||
struct exe_header_t
|
||||
{
|
||||
@@ -98,6 +99,7 @@ protected:
|
||||
unsigned relocsize;
|
||||
|
||||
bool has_9a;
|
||||
bool device_driver;
|
||||
|
||||
enum {
|
||||
NORELOC = 1,
|
||||
|
||||
+1938
-283
File diff suppressed because it is too large
Load Diff
+380
-33
@@ -2,9 +2,9 @@
|
||||
|
||||
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
|
||||
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
|
||||
@@ -22,8 +22,11 @@
|
||||
If not, write to the Free Software Foundation, Inc.,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
Markus F.X.J. Oberhumer Laszlo Molnar John F. Reiser
|
||||
markus@oberhumer.com ml1050@cdata.tvnet.hu jreiser@BitWagon.com
|
||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
||||
|
||||
John F. Reiser
|
||||
<jreiser@users.sourceforge.net>
|
||||
*/
|
||||
|
||||
|
||||
@@ -31,53 +34,397 @@
|
||||
#define __UPX_P_LX_ELF_H
|
||||
|
||||
|
||||
class PackLinuxElf : public PackUnix
|
||||
{
|
||||
typedef PackUnix super;
|
||||
public:
|
||||
PackLinuxElf(InputFile *f);
|
||||
virtual ~PackLinuxElf();
|
||||
/*virtual int buildLoader(const Filter *);*/
|
||||
virtual bool canUnpackVersion(int version) const { return (version >= 11); }
|
||||
|
||||
protected:
|
||||
virtual const int *getCompressionMethods(int method, int level) const;
|
||||
|
||||
// All other virtual functions in this class must be pure virtual
|
||||
// because they depend on Elf32 or Elf64 data structures, which differ.
|
||||
|
||||
virtual void pack1(OutputFile *, Filter &) = 0; // generate executable header
|
||||
virtual void pack2(OutputFile *, Filter &) = 0; // append compressed data
|
||||
virtual void pack3(OutputFile *, Filter &) = 0; // append loader
|
||||
//virtual void pack4(OutputFile *, Filter &) = 0; // append pack header
|
||||
|
||||
virtual void generateElfHdr(
|
||||
OutputFile *,
|
||||
void const *proto,
|
||||
unsigned const brka
|
||||
) = 0;
|
||||
virtual void defineSymbols(Filter const *);
|
||||
virtual void addStubEntrySections(Filter const *);
|
||||
virtual void unpack(OutputFile *fo) = 0;
|
||||
|
||||
protected:
|
||||
char *file_image; // if ET_DYN investigation
|
||||
char const *dynstr; // from DT_STRTAB
|
||||
|
||||
unsigned sz_phdrs; // sizeof Phdr[]
|
||||
unsigned sz_elf_hdrs; // all Elf headers
|
||||
unsigned sz_pack2; // after pack2(), before loader
|
||||
|
||||
unsigned short e_machine;
|
||||
unsigned char ei_class;
|
||||
unsigned char ei_data;
|
||||
unsigned char ei_osabi;
|
||||
char const *osabi_note;
|
||||
};
|
||||
|
||||
class PackLinuxElf32 : public PackLinuxElf
|
||||
{
|
||||
typedef PackLinuxElf super;
|
||||
public:
|
||||
PackLinuxElf32(InputFile *f);
|
||||
virtual ~PackLinuxElf32();
|
||||
protected:
|
||||
virtual int checkEhdr(Elf32_Ehdr const *ehdr) const;
|
||||
virtual bool canPack();
|
||||
|
||||
// These ARM routines are essentially common to big/little endian,
|
||||
// but the class hierarchy splits after this class.
|
||||
virtual int ARM_buildLoader(Filter const *ft, bool isBE);
|
||||
virtual void ARM_defineSymbols(Filter const *ft);
|
||||
virtual void ARM_updateLoader(OutputFile *);
|
||||
virtual void ARM_pack1(OutputFile *, bool isBE);
|
||||
|
||||
virtual void pack1(OutputFile *, Filter &); // generate executable header
|
||||
virtual void pack2(OutputFile *, Filter &); // append compressed data
|
||||
virtual void pack3(OutputFile *, Filter &); // append loader
|
||||
virtual void pack4(OutputFile *, Filter &); // append pack header
|
||||
virtual void unpack(OutputFile *fo);
|
||||
|
||||
virtual void generateElfHdr(
|
||||
OutputFile *,
|
||||
void const *proto,
|
||||
unsigned const brka
|
||||
);
|
||||
virtual 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 off_t getbrk(const Elf32_Phdr *phdr, int e_phnum) const;
|
||||
virtual void patchLoader();
|
||||
virtual void updateLoader(OutputFile *fo);
|
||||
virtual unsigned find_LOAD_gap(Elf32_Phdr const *const phdri, unsigned const k,
|
||||
unsigned const e_phnum);
|
||||
virtual off_t getbase(const Elf32_Phdr *phdr, int e_phnum) const;
|
||||
|
||||
static unsigned elf_hash(char const *) /*const*/;
|
||||
virtual void const *elf_find_dynamic(unsigned) const;
|
||||
virtual Elf32_Sym const *elf_lookup(char const *) const;
|
||||
virtual unsigned elf_get_offset_from_address(unsigned) const;
|
||||
|
||||
protected:
|
||||
Elf32_Ehdr ehdri; // from input file
|
||||
Elf32_Phdr *phdri; // for input file
|
||||
|
||||
Elf32_Dyn const *dynseg; // from PT_DYNAMIC
|
||||
unsigned int const *hashtab; // from DT_HASH
|
||||
Elf32_Sym const *dynsym; // from DT_SYMTAB
|
||||
|
||||
struct cprElfHdr1 {
|
||||
Elf32_Ehdr ehdr;
|
||||
Elf32_Phdr phdr[1];
|
||||
l_info linfo;
|
||||
}
|
||||
__attribute_packed;
|
||||
|
||||
struct cprElfHdr2 {
|
||||
Elf32_Ehdr ehdr;
|
||||
Elf32_Phdr phdr[2];
|
||||
l_info linfo;
|
||||
}
|
||||
__attribute_packed;
|
||||
|
||||
struct cprElfHdr3 {
|
||||
Elf32_Ehdr ehdr;
|
||||
Elf32_Phdr phdr[3];
|
||||
l_info linfo;
|
||||
}
|
||||
__attribute_packed;
|
||||
|
||||
cprElfHdr3 elfout;
|
||||
|
||||
struct Elf32_Note {
|
||||
unsigned namesz; // 8
|
||||
unsigned descsz; // 4
|
||||
unsigned type; // 1
|
||||
char text[0x18 - 4*4]; // "OpenBSD"
|
||||
unsigned end; // 0
|
||||
} elfnote;
|
||||
};
|
||||
|
||||
|
||||
class PackLinuxElf64 : public PackLinuxElf
|
||||
{
|
||||
typedef PackLinuxElf super;
|
||||
public:
|
||||
PackLinuxElf64(InputFile *f);
|
||||
virtual ~PackLinuxElf64();
|
||||
/*virtual int buildLoader(const Filter *);*/
|
||||
|
||||
protected:
|
||||
virtual int checkEhdr(Elf64_Ehdr const *ehdr) const;
|
||||
|
||||
virtual void pack1(OutputFile *, Filter &); // generate executable header
|
||||
virtual void pack2(OutputFile *, Filter &); // append compressed data
|
||||
virtual void pack3(OutputFile *, Filter &); // append loader
|
||||
virtual void pack4(OutputFile *, Filter &); // append pack header
|
||||
virtual void unpack(OutputFile *fo);
|
||||
|
||||
virtual void generateElfHdr(
|
||||
OutputFile *,
|
||||
void const *proto,
|
||||
unsigned const brka
|
||||
);
|
||||
virtual 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 off_t getbrk(const Elf64_Phdr *phdr, int e_phnum) const;
|
||||
virtual void patchLoader();
|
||||
virtual void updateLoader(OutputFile *fo);
|
||||
virtual unsigned find_LOAD_gap(Elf64_Phdr const *const phdri, unsigned const k,
|
||||
unsigned const e_phnum);
|
||||
|
||||
protected:
|
||||
Elf64_Ehdr ehdri; // from input file
|
||||
Elf64_Phdr *phdri; // for input file
|
||||
|
||||
struct cprElfHdr1 {
|
||||
Elf64_Ehdr ehdr;
|
||||
Elf64_Phdr phdr[1];
|
||||
l_info linfo;
|
||||
}
|
||||
__attribute_packed;
|
||||
|
||||
struct cprElfHdr2 {
|
||||
Elf64_Ehdr ehdr;
|
||||
Elf64_Phdr phdr[2];
|
||||
l_info linfo;
|
||||
}
|
||||
__attribute_packed;
|
||||
|
||||
struct cprElfHdr3 {
|
||||
Elf64_Ehdr ehdr;
|
||||
Elf64_Phdr phdr[3];
|
||||
l_info linfo;
|
||||
}
|
||||
__attribute_packed;
|
||||
|
||||
cprElfHdr3 elfout;
|
||||
};
|
||||
|
||||
class PackLinuxElf32Be : public PackLinuxElf32
|
||||
{
|
||||
typedef PackLinuxElf32 super;
|
||||
protected:
|
||||
PackLinuxElf32Be(InputFile *f) : super(f) { }
|
||||
|
||||
virtual acc_uint64l_t get_native64(const void *b) const { return get_be64(b); }
|
||||
virtual unsigned get_native32(const void *b) const { return get_be32(b); }
|
||||
virtual unsigned get_native16(const void *b) const { return get_be16(b); }
|
||||
virtual void set_native64(void *b, acc_uint64l_t v) const { set_be64(b, v); }
|
||||
virtual void set_native32(void *b, unsigned v) const { set_be32(b, v); }
|
||||
virtual void set_native16(void *b, unsigned v) const { set_be16(b, v); }
|
||||
};
|
||||
|
||||
class PackLinuxElf32Le : public PackLinuxElf32
|
||||
{
|
||||
typedef PackLinuxElf32 super;
|
||||
protected:
|
||||
PackLinuxElf32Le(InputFile *f) : super(f) { }
|
||||
|
||||
virtual acc_uint64l_t get_native64(const void *b) const { return get_le64(b); }
|
||||
virtual unsigned get_native32(const void *b) const { return get_le32(b); }
|
||||
virtual unsigned get_native16(const void *b) const { return get_le16(b); }
|
||||
virtual void set_native64(void *b, acc_uint64l_t v) const { set_le64(b, v); }
|
||||
virtual void set_native32(void *b, unsigned v) const { set_le32(b, v); }
|
||||
virtual void set_native16(void *b, unsigned v) const { set_le16(b, v); }
|
||||
};
|
||||
|
||||
class PackLinuxElf64Le : public PackLinuxElf64
|
||||
{
|
||||
typedef PackLinuxElf64 super;
|
||||
protected:
|
||||
PackLinuxElf64Le(InputFile *f) : super(f) { }
|
||||
|
||||
virtual acc_uint64l_t get_native64(const void *b) const { return get_le64(b); }
|
||||
virtual unsigned get_native32(const void *b) const { return get_le32(b); }
|
||||
virtual unsigned get_native16(const void *b) const { return get_le16(b); }
|
||||
virtual void set_native64(void *b, acc_uint64l_t v) const { set_le64(b, v); }
|
||||
virtual void set_native32(void *b, unsigned v) const { set_le32(b, v); }
|
||||
virtual void set_native16(void *b, unsigned v) const { set_le16(b, v); }
|
||||
};
|
||||
|
||||
/*************************************************************************
|
||||
// linux/elf64amd
|
||||
**************************************************************************/
|
||||
|
||||
class PackLinuxElf64amd : public PackLinuxElf64Le
|
||||
{
|
||||
typedef PackLinuxElf64Le super;
|
||||
public:
|
||||
PackLinuxElf64amd(InputFile *f);
|
||||
virtual ~PackLinuxElf64amd();
|
||||
virtual int getFormat() const { return UPX_F_LINUX_ELF64_AMD; }
|
||||
virtual const char *getName() const { return "linux/ElfAMD"; }
|
||||
virtual const int *getFilters() const;
|
||||
virtual bool canPack();
|
||||
protected:
|
||||
virtual void pack1(OutputFile *, Filter &); // generate executable header
|
||||
//virtual void pack3(OutputFile *, Filter &); // append loader
|
||||
virtual int buildLoader(const Filter *);
|
||||
virtual Linker* newLinker() const;
|
||||
virtual void defineSymbols(Filter const *);
|
||||
};
|
||||
|
||||
/*************************************************************************
|
||||
// linux/elf32ppc
|
||||
**************************************************************************/
|
||||
|
||||
class PackLinuxElf32ppc : public PackLinuxElf32Be
|
||||
{
|
||||
typedef PackLinuxElf32Be super;
|
||||
public:
|
||||
PackLinuxElf32ppc(InputFile *f);
|
||||
virtual ~PackLinuxElf32ppc();
|
||||
virtual int getFormat() const { return UPX_F_LINUX_ELFPPC32; }
|
||||
virtual const char *getName() const { return "linux/ElfPPC"; }
|
||||
virtual const int *getFilters() const;
|
||||
protected:
|
||||
virtual void pack1(OutputFile *, Filter &); // generate executable header
|
||||
virtual int buildLoader(const Filter *);
|
||||
virtual Linker* newLinker() const;
|
||||
};
|
||||
|
||||
/*************************************************************************
|
||||
// linux/elf386
|
||||
**************************************************************************/
|
||||
|
||||
class PackLinuxI386elf : public PackLinuxI386
|
||||
class PackLinuxElf32x86 : public PackLinuxElf32Le
|
||||
{
|
||||
typedef PackLinuxI386 super;
|
||||
typedef PackLinuxElf32Le super;
|
||||
public:
|
||||
PackLinuxI386elf(InputFile *f);
|
||||
virtual ~PackLinuxI386elf();
|
||||
virtual int getVersion() const { return 13; }
|
||||
PackLinuxElf32x86(InputFile *f);
|
||||
virtual ~PackLinuxElf32x86();
|
||||
virtual int getFormat() const { return UPX_F_LINUX_ELF_i386; }
|
||||
virtual const char *getName() const { return "linux/elf386"; }
|
||||
virtual const int *getFilters() const;
|
||||
virtual int buildLoader(const Filter *);
|
||||
|
||||
virtual void unpack(OutputFile *fo);
|
||||
|
||||
virtual bool canPack();
|
||||
virtual bool canUnpackVersion(int version) const
|
||||
{ return (version >= 11); }
|
||||
|
||||
protected:
|
||||
struct Extent {
|
||||
off_t offset;
|
||||
off_t size;
|
||||
};
|
||||
virtual void packExtent(const Extent &x,
|
||||
unsigned &total_in, unsigned &total_out, Filter *, OutputFile *);
|
||||
virtual void unpackExtent(unsigned wanted, OutputFile *fo,
|
||||
unsigned &total_in, unsigned &total_out,
|
||||
unsigned &c_adler, unsigned &u_adler,
|
||||
bool first_PF_X, unsigned szb_info );
|
||||
virtual void pack1(OutputFile *, Filter &); // generate executable header
|
||||
|
||||
virtual int buildLoader(const Filter *);
|
||||
virtual void addStubEntrySections(Filter const *);
|
||||
virtual Linker* newLinker() const;
|
||||
virtual void defineSymbols(Filter const *);
|
||||
};
|
||||
|
||||
class PackBSDElf32x86 : public PackLinuxElf32x86
|
||||
{
|
||||
typedef PackLinuxElf32x86 super;
|
||||
public:
|
||||
PackBSDElf32x86(InputFile *f);
|
||||
virtual ~PackBSDElf32x86();
|
||||
virtual int getFormat() const { return UPX_F_BSD_ELF_i386; }
|
||||
virtual const char *getName() const { return "BSD/elf386"; }
|
||||
|
||||
protected:
|
||||
virtual void pack1(OutputFile *, Filter &); // generate executable header
|
||||
virtual void pack2(OutputFile *, Filter &); // append compressed data
|
||||
virtual void pack3(OutputFile *, Filter &); // append loader
|
||||
|
||||
virtual void patchLoader();
|
||||
|
||||
Elf_LE32_Ehdr ehdri; // from input file
|
||||
Elf_LE32_Phdr *phdri; // for input file
|
||||
unsigned sz_phdrs; // sizeof Phdr[]
|
||||
|
||||
virtual int buildLoader(const Filter *);
|
||||
};
|
||||
|
||||
class PackFreeBSDElf32x86 : public PackBSDElf32x86
|
||||
{
|
||||
typedef PackBSDElf32x86 super;
|
||||
public:
|
||||
PackFreeBSDElf32x86(InputFile *f);
|
||||
virtual ~PackFreeBSDElf32x86();
|
||||
};
|
||||
|
||||
class PackNetBSDElf32x86 : public PackBSDElf32x86
|
||||
{
|
||||
typedef PackBSDElf32x86 super;
|
||||
public:
|
||||
PackNetBSDElf32x86(InputFile *f);
|
||||
virtual ~PackNetBSDElf32x86();
|
||||
};
|
||||
|
||||
class PackOpenBSDElf32x86 : public PackBSDElf32x86
|
||||
{
|
||||
typedef PackBSDElf32x86 super;
|
||||
public:
|
||||
PackOpenBSDElf32x86(InputFile *f);
|
||||
virtual ~PackOpenBSDElf32x86();
|
||||
|
||||
protected:
|
||||
virtual int buildLoader(const Filter *ft);
|
||||
virtual void generateElfHdr(
|
||||
OutputFile *,
|
||||
void const *proto,
|
||||
unsigned const brka
|
||||
);
|
||||
};
|
||||
|
||||
/*************************************************************************
|
||||
// linux/elfarm
|
||||
**************************************************************************/
|
||||
|
||||
class PackLinuxElf32armLe : public PackLinuxElf32Le
|
||||
{
|
||||
typedef PackLinuxElf32Le super;
|
||||
public:
|
||||
PackLinuxElf32armLe(InputFile *f);
|
||||
virtual ~PackLinuxElf32armLe();
|
||||
virtual int getFormat() const { return UPX_F_LINUX_ELF32_ARMLE; }
|
||||
virtual const char *getName() const { return "linux/armLE"; }
|
||||
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 int 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_ARMBE; }
|
||||
virtual const char *getName() const { return "linux/armBE"; }
|
||||
virtual const int *getFilters() const;
|
||||
|
||||
protected:
|
||||
virtual const int *getCompressionMethods(int method, int level) const;
|
||||
virtual Linker* newLinker() const;
|
||||
virtual void pack1(OutputFile *, Filter &); // generate executable header
|
||||
virtual int buildLoader(const Filter *);
|
||||
virtual void updateLoader(OutputFile *);
|
||||
virtual void defineSymbols(Filter const *);
|
||||
};
|
||||
|
||||
#endif /*} already included */
|
||||
|
||||
|
||||
+288
-198
@@ -2,9 +2,9 @@
|
||||
|
||||
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) 2001-2004 John F. Reiser
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
Copyright (C) 2001-2006 John F. Reiser
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -22,8 +22,11 @@
|
||||
If not, write to the Free Software Foundation, Inc.,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
Markus F.X.J. Oberhumer Laszlo Molnar John F. Reiser
|
||||
markus@oberhumer.com ml1050@cdata.tvnet.hu jreiser@BitWagon.com
|
||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
||||
|
||||
John F. Reiser
|
||||
<jreiser@users.sourceforge.net>
|
||||
*/
|
||||
|
||||
|
||||
@@ -37,22 +40,48 @@
|
||||
#include "p_unix.h"
|
||||
#include "p_lx_exc.h"
|
||||
|
||||
#define PT_LOAD Elf_LE32_Phdr::PT_LOAD
|
||||
#define PT_DYNAMIC Elf_LE32_Phdr::PT_DYNAMIC
|
||||
#define DT_NULL Elf_LE32_Dyn::DT_NULL
|
||||
#define DT_NEEDED Elf_LE32_Dyn::DT_NEEDED
|
||||
#define DT_STRTAB Elf_LE32_Dyn::DT_STRTAB
|
||||
#define DT_STRSZ Elf_LE32_Dyn::DT_STRSZ
|
||||
#define PT_LOAD Elf32_Phdr::PT_LOAD
|
||||
#define PT_DYNAMIC Elf32_Phdr::PT_DYNAMIC
|
||||
#if 0 // UNUSED
|
||||
#define DT_NULL Elf32_Dyn::DT_NULL
|
||||
#define DT_NEEDED Elf32_Dyn::DT_NEEDED
|
||||
#define DT_STRTAB Elf32_Dyn::DT_STRTAB
|
||||
#define DT_STRSZ Elf32_Dyn::DT_STRSZ
|
||||
#endif
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// linux/386 (generic "execve" format)
|
||||
**************************************************************************/
|
||||
|
||||
PackLinuxI386::PackLinuxI386(InputFile *f) : super(f),
|
||||
ei_osabi(Elf32_Ehdr::ELFOSABI_LINUX), osabi_note(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
PackBSDI386::PackBSDI386(InputFile *f) : super(f)
|
||||
{
|
||||
// Shell scripts need help specifying the target operating system.
|
||||
// Elf input will override this with .e_ident[EI_OSABI] or PT_NOTE.
|
||||
// [2006-09-27: Today's only runtime stub for shell is for linux.]
|
||||
if (Elf32_Ehdr::ELFOSABI_LINUX==opt->o_unix.osabi0) {
|
||||
// Disallow an incompatibility.
|
||||
ei_osabi = Elf32_Ehdr::ELFOSABI_NONE;
|
||||
}
|
||||
else {
|
||||
ei_osabi = opt->o_unix.osabi0; // might be ELFOSABI_NONE
|
||||
}
|
||||
}
|
||||
|
||||
static const
|
||||
#include "stub/l_lx_exec86.h"
|
||||
#include "stub/i386-linux.elf.execve-entry.h"
|
||||
static const
|
||||
#include "stub/fold_exec86.h"
|
||||
#include "stub/i386-linux.elf.execve-fold.h"
|
||||
|
||||
static const
|
||||
#include "stub/i386-bsd.elf.execve-entry.h"
|
||||
static const
|
||||
#include "stub/i386-bsd.elf.execve-fold.h"
|
||||
|
||||
|
||||
const int *PackLinuxI386::getCompressionMethods(int method, int level) const
|
||||
@@ -64,14 +93,9 @@ const int *PackLinuxI386::getFilters() const
|
||||
{
|
||||
static const int filters[] = {
|
||||
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,
|
||||
#endif
|
||||
#if 0
|
||||
// 0x80..0x87 are regarded as "untested".
|
||||
0x83, 0x86, 0x80, 0x84, 0x87, 0x81, 0x82, 0x85,
|
||||
0x24, 0x16, 0x13, 0x14, 0x11, 0x25, 0x15, 0x12,
|
||||
#endif
|
||||
@@ -79,6 +103,27 @@ const int *PackLinuxI386::getFilters() const
|
||||
return filters;
|
||||
}
|
||||
|
||||
static void
|
||||
set_stub_brk(Elf_LE32_Phdr *const phdr1, unsigned brka)
|
||||
{
|
||||
#define PAGE_MASK (~0ul<<12)
|
||||
// linux-2.6.14 binfmt_elf.c: SIGKILL if (0==.p_memsz) on a page boundary
|
||||
unsigned const brkb = brka | ((0==(~PAGE_MASK & brka)) ? 0x20 : 0);
|
||||
phdr1->p_type = PT_LOAD; // be sure
|
||||
phdr1->p_offset = ~PAGE_MASK & brkb;
|
||||
phdr1->p_vaddr = brkb;
|
||||
phdr1->p_paddr = brkb;
|
||||
phdr1->p_filesz = 0;
|
||||
phdr1->p_memsz = 0;
|
||||
if (0==phdr1->p_flags) {
|
||||
phdr1->p_flags = Elf32_Phdr::PF_R|Elf32_Phdr::PF_W;
|
||||
}
|
||||
if (0==phdr1->p_align) {
|
||||
phdr1->p_align = 0x1000;
|
||||
}
|
||||
#undef PAGE_MASK
|
||||
}
|
||||
|
||||
void
|
||||
PackLinuxI386::generateElfHdr(
|
||||
OutputFile *fo,
|
||||
@@ -86,14 +131,14 @@ PackLinuxI386::generateElfHdr(
|
||||
unsigned const brka
|
||||
)
|
||||
{
|
||||
cprElfHdr1 *const h1 = (cprElfHdr1 *)&elfout;
|
||||
cprElfHdr2 *const h2 = (cprElfHdr2 *)&elfout;
|
||||
memcpy(h2, proto, sizeof(*h2));
|
||||
cprElfHdr3 *const h3 = (cprElfHdr3 *)&elfout;
|
||||
memcpy(h3, proto, sizeof(*h3)); // reads beyond, but OK
|
||||
|
||||
assert(h2->ehdr.e_phoff == sizeof(Elf_LE32_Ehdr));
|
||||
assert(h2->ehdr.e_phoff == sizeof(Elf32_Ehdr));
|
||||
assert(h2->ehdr.e_shoff == 0);
|
||||
assert(h2->ehdr.e_ehsize == sizeof(Elf_LE32_Ehdr));
|
||||
assert(h2->ehdr.e_phentsize == sizeof(Elf_LE32_Phdr));
|
||||
assert(h2->ehdr.e_ehsize == sizeof(Elf32_Ehdr));
|
||||
assert(h2->ehdr.e_phentsize == sizeof(Elf32_Phdr));
|
||||
assert(h2->ehdr.e_shnum == 0);
|
||||
|
||||
#if 0 //{
|
||||
@@ -105,29 +150,26 @@ PackLinuxI386::generateElfHdr(
|
||||
|
||||
// Info for OS kernel to set the brk()
|
||||
if (brka) {
|
||||
h2->phdr[1].p_type = PT_LOAD; // be sure
|
||||
h2->phdr[1].p_offset = 0xfff&brka;
|
||||
h2->phdr[1].p_vaddr = brka;
|
||||
h2->phdr[1].p_paddr = brka;
|
||||
h2->phdr[1].p_filesz = 0;
|
||||
h2->phdr[1].p_memsz = 0;
|
||||
set_stub_brk(&h2->phdr[1], brka);
|
||||
}
|
||||
|
||||
if (ph.format==UPX_F_LINUX_i386 ) {
|
||||
assert(h1->ehdr.e_phnum==1);
|
||||
memset(&h1->linfo, 0, sizeof(h1->linfo));
|
||||
fo->write(h1, sizeof(*h1));
|
||||
}
|
||||
else if (ph.format==UPX_F_LINUX_ELF_i386) {
|
||||
if (ph.format==UPX_F_LINUX_i386
|
||||
|| ph.format==UPX_F_LINUX_SH_i386
|
||||
|| ph.format==UPX_F_BSD_i386
|
||||
) {
|
||||
// SELinux, PAx, grSecurity demand no PF_W if PF_X.
|
||||
// kernel-2.6.12-2.3.legacy_FC3 has a bug which demands
|
||||
// a PT_LOAD with PF_W, else SIGSEGV when clearing page fragment
|
||||
// on low page of ".bss", which is the high page of .text.
|
||||
// So the minimum number of PT_LOAD is 2.
|
||||
assert(h2->ehdr.e_phnum==2);
|
||||
memset(&h2->linfo, 0, sizeof(h2->linfo));
|
||||
fo->write(h2, sizeof(*h2));
|
||||
}
|
||||
else if (ph.format==UPX_F_LINUX_SH_i386) {
|
||||
assert(h2->ehdr.e_phnum==1);
|
||||
h2->ehdr.e_phnum = 2;
|
||||
memset(&h2->linfo, 0, sizeof(h2->linfo));
|
||||
fo->write(h2, sizeof(*h2));
|
||||
else if (ph.format==UPX_F_LINUX_ELFI_i386) {
|
||||
assert(h3->ehdr.e_phnum==3);
|
||||
memset(&h3->linfo, 0, sizeof(h3->linfo));
|
||||
fo->write(h3, sizeof(*h3));
|
||||
}
|
||||
else {
|
||||
assert(false); // unknown ph.format, PackUnix::generateElfHdr
|
||||
@@ -143,6 +185,15 @@ PackLinuxI386::pack1(OutputFile *fo, Filter &)
|
||||
generateElfHdr(fo, linux_i386exec_fold, 0);
|
||||
}
|
||||
|
||||
void
|
||||
PackBSDI386::pack1(OutputFile *fo, Filter &)
|
||||
{
|
||||
// create a pseudo-unique program id for our paranoid stub
|
||||
progid = getRandomId();
|
||||
|
||||
generateElfHdr(fo, bsd_i386exec_fold, 0);
|
||||
}
|
||||
|
||||
void
|
||||
PackLinuxI386::pack4(OutputFile *fo, Filter &ft)
|
||||
{
|
||||
@@ -150,10 +201,11 @@ PackLinuxI386::pack4(OutputFile *fo, Filter &ft)
|
||||
(elfout.ehdr.e_phentsize * elfout.ehdr.e_phnum) +
|
||||
sizeof(l_info) +
|
||||
((elfout.ehdr.e_phnum==3) ? (unsigned) elfout.phdr[2].p_memsz : 0) ;
|
||||
unsigned nw = fo->getBytesWritten();
|
||||
elfout.phdr[0].p_filesz = nw;
|
||||
nw = -(-elfout.phdr[0].p_align & -nw); // ALIGN_UP
|
||||
super::pack4(fo, ft); // write PackHeader and overlay_offset
|
||||
|
||||
unsigned eod = fo->getBytesWritten();
|
||||
elfout.phdr[0].p_filesz = eod;
|
||||
set_stub_brk(&elfout.phdr[1], nw + elfout.phdr[0].p_vaddr);
|
||||
|
||||
#if 0 // {
|
||||
// /usr/bin/strip from RedHat 8.0 (binutils-2.13.90.0.2-2)
|
||||
@@ -174,48 +226,56 @@ PackLinuxI386::pack4(OutputFile *fo, Filter &ft)
|
||||
// The section header string table.
|
||||
char const shstrtab[] = "\0.\0.shstrtab";
|
||||
|
||||
set_native32(&elfout.ehdr.e_shoff, eod);
|
||||
set_native16(&elfout.ehdr.e_shentsize, sizeof(shdr));
|
||||
set_native16(&elfout.ehdr.e_shnum, 3);
|
||||
set_native16(&elfout.ehdr.e_shstrndx, 2);
|
||||
unsigned eod = elfout.phdr[0].p_filesz;
|
||||
elfout.ehdr.e_shoff = eod;
|
||||
elfout.ehdr.e_shentsize = sizeof(shdr);
|
||||
elfout.ehdr.e_shnum = 3;
|
||||
elfout.ehdr.e_shstrndx = 2;
|
||||
|
||||
// An empty Elf32_Shdr for space as a null index.
|
||||
memset(&shdr, 0, sizeof(shdr));
|
||||
set_native32(&shdr.sh_type, Elf_LE32_Shdr::SHT_NULL);
|
||||
shdr.sh_type = Elf32_Shdr::SHT_NULL;
|
||||
fo->write(&shdr, sizeof(shdr));
|
||||
|
||||
// Cover all the bits we need at runtime.
|
||||
memset(&shdr, 0, sizeof(shdr));
|
||||
set_native32(&shdr.sh_name, 1);
|
||||
set_native32(&shdr.sh_type, Elf_LE32_Shdr::SHT_PROGBITS);
|
||||
set_native32(&shdr.sh_flags, Elf_LE32_Shdr::SHF_ALLOC);
|
||||
set_native32(&shdr.sh_addr, elfout.phdr[0].p_vaddr);
|
||||
set_native32(&shdr.sh_offset, overlay_offset);
|
||||
set_native32(&shdr.sh_size, eod - overlay_offset);
|
||||
set_native32(&shdr.sh_addralign, 4096);
|
||||
shdr.sh_name = 1;
|
||||
shdr.sh_type = Elf32_Shdr::SHT_PROGBITS;
|
||||
shdr.sh_flags = Elf32_Shdr::SHF_ALLOC;
|
||||
shdr.sh_addr = elfout.phdr[0].p_vaddr;
|
||||
shdr.sh_offset = overlay_offset;
|
||||
shdr.sh_size = eod - overlay_offset;
|
||||
shdr.sh_addralign = 4096;
|
||||
fo->write(&shdr, sizeof(shdr));
|
||||
|
||||
// A section header for the section header string table.
|
||||
memset(&shdr, 0, sizeof(shdr));
|
||||
set_native32(&shdr.sh_name, 3);
|
||||
set_native32(&shdr.sh_type, Elf_LE32_Shdr::SHT_STRTAB);
|
||||
set_native32(&shdr.sh_offset, 3*sizeof(shdr) + eod);
|
||||
set_native32(&shdr.sh_size, sizeof(shstrtab));
|
||||
shdr.sh_name = 3;
|
||||
shdr.sh_type = Elf32_Shdr::SHT_STRTAB;
|
||||
shdr.sh_offset = 3*sizeof(shdr) + eod;
|
||||
shdr.sh_size = sizeof(shstrtab);
|
||||
fo->write(&shdr, sizeof(shdr));
|
||||
|
||||
fo->write(shstrtab, sizeof(shstrtab));
|
||||
#endif // }
|
||||
|
||||
|
||||
// Cannot pre-round .p_memsz. If .p_filesz < .p_memsz, then kernel
|
||||
// tries to make .bss, which requires PF_W.
|
||||
// But strict SELinux (or PaX, grSecurity) disallows PF_W with PF_X.
|
||||
#if 0 /*{*/
|
||||
#undef PAGE_MASK
|
||||
#define PAGE_MASK (~0u<<12)
|
||||
// pre-calculate for benefit of runtime disappearing act via munmap()
|
||||
elfout.phdr[0].p_memsz = PAGE_MASK & (~PAGE_MASK + elfout.phdr[0].p_filesz);
|
||||
#undef PAGE_MASK
|
||||
#else /*}{*/
|
||||
elfout.phdr[0].p_memsz = elfout.phdr[0].p_filesz;
|
||||
#endif /*}*/
|
||||
|
||||
// rewrite Elf header
|
||||
fo->seek(0, SEEK_SET);
|
||||
fo->rewrite(&elfout, sizeof(elfout.ehdr) +
|
||||
elfout.ehdr.e_phnum * sizeof(elfout.phdr[0]) +
|
||||
sizeof(l_info) );
|
||||
fo->rewrite(&elfout, overlay_offset);
|
||||
}
|
||||
|
||||
static unsigned
|
||||
@@ -227,6 +287,11 @@ umax(unsigned a, unsigned b)
|
||||
return a;
|
||||
}
|
||||
|
||||
Linker *PackLinuxI386::newLinker() const
|
||||
{
|
||||
return new ElfLinkerX86;
|
||||
}
|
||||
|
||||
int
|
||||
PackLinuxI386::buildLinuxLoader(
|
||||
upx_byte const *const proto,
|
||||
@@ -238,119 +303,97 @@ PackLinuxI386::buildLinuxLoader(
|
||||
{
|
||||
initLoader(proto, szproto);
|
||||
|
||||
unsigned fold_hdrlen = 0;
|
||||
if (0 < szfold) {
|
||||
cprElfHdr1 const *const hf = (cprElfHdr1 const *)fold;
|
||||
unsigned const fold_hdrlen = umax(0x80, sizeof(hf->ehdr) +
|
||||
hf->ehdr.e_phentsize * hf->ehdr.e_phnum + sizeof(l_info) );
|
||||
struct b_info h; memset(&h, 0, sizeof(h));
|
||||
h.sz_unc = szfold - fold_hdrlen;
|
||||
h.b_method = (unsigned char) ph.method;
|
||||
h.b_ftid = (unsigned char) ph.filter;
|
||||
h.b_cto8 = (unsigned char) ph.filter_cto;
|
||||
unsigned char const *const uncLoader = fold_hdrlen + fold;
|
||||
|
||||
unsigned char *const cprLoader = new unsigned char[sizeof(h) + h.sz_unc];
|
||||
int r = upx_compress(uncLoader, h.sz_unc, sizeof(h) + cprLoader, &h.sz_cpr,
|
||||
NULL, ph.method, 10, NULL, NULL );
|
||||
if (r != UPX_E_OK || h.sz_cpr >= h.sz_unc)
|
||||
throwInternalError("loader compression failed");
|
||||
memcpy(cprLoader, &h, sizeof(h));
|
||||
|
||||
fold_hdrlen = sizeof(hf->ehdr) + hf->ehdr.e_phentsize * hf->ehdr.e_phnum +
|
||||
sizeof(l_info);
|
||||
if (0 == get_le32(fold_hdrlen + fold)) {
|
||||
// inconsistent SIZEOF_HEADERS in *.lds (ld, binutils)
|
||||
fold_hdrlen = umax(0x80, fold_hdrlen);
|
||||
}
|
||||
}
|
||||
// This adds the definition to the "library", to be used later.
|
||||
linker->addSection("FOLDEXEC", cprLoader, sizeof(h) + h.sz_cpr);
|
||||
delete [] cprLoader;
|
||||
// NOTE: the stub is NOT compressed! The savings is not worth it.
|
||||
linker->addSection("FOLDEXEC", fold + fold_hdrlen, szfold - fold_hdrlen, 0);
|
||||
|
||||
n_mru = ft->n_mru;
|
||||
|
||||
// Here is a quick summary of the format of the output file:
|
||||
linker->setLoaderAlignOffset(
|
||||
// Elf32_Edhr
|
||||
sizeof(elfout.ehdr) +
|
||||
// Elf32_Phdr: 1 for exec86, 2 for sh86, 3 for elf86
|
||||
(elfout.ehdr.e_phentsize * elfout.ehdr.e_phnum) +
|
||||
// checksum UPX! lsize version format
|
||||
sizeof(l_info) +
|
||||
// PT_DYNAMIC with DT_NEEDED "forwarded" from original file
|
||||
((elfout.ehdr.e_phnum==3) ? (unsigned) elfout.phdr[2].p_memsz : 0) +
|
||||
// p_progid, p_filesize, p_blocksize
|
||||
sizeof(p_info) +
|
||||
// compressed data
|
||||
b_len + ph.c_len );
|
||||
// entry to stub
|
||||
addLoader("LEXEC000", 0);
|
||||
// Rely on "+80CXXXX" [etc] in getDecompressorSections() packer_c.cpp */
|
||||
// // Here is a quick summary of the format of the output file:
|
||||
// linker->setLoaderAlignOffset(
|
||||
// // Elf32_Edhr
|
||||
// sizeof(elfout.ehdr) +
|
||||
// // Elf32_Phdr: 1 for exec86, 2 for sh86, 3 for elf86
|
||||
// (elfout.ehdr.e_phentsize * elfout.ehdr.e_phnum) +
|
||||
// // checksum UPX! lsize version format
|
||||
// sizeof(l_info) +
|
||||
// // PT_DYNAMIC with DT_NEEDED "forwarded" from original file
|
||||
// ((elfout.ehdr.e_phnum==3) ? (unsigned) elfout.phdr[2].p_memsz : 0) +
|
||||
// // p_progid, p_filesize, p_blocksize
|
||||
// sizeof(p_info) +
|
||||
// // compressed data
|
||||
// b_len + ph.c_len );
|
||||
// // entry to stub
|
||||
addLoader("LEXEC000", NULL);
|
||||
|
||||
if (ft->id) {
|
||||
if (ph.format==UPX_F_LINUX_ELF_i386) { // decompr, unfilter are separate
|
||||
addLoader("LXUNF000", 0);
|
||||
addLoader("LXUNF002", 0);
|
||||
if (0x80==(ft->id & 0xF0)) {
|
||||
if (256==n_mru) {
|
||||
addLoader("MRUBYTE0", 0);
|
||||
}
|
||||
else if (n_mru) {
|
||||
addLoader("LXMRU005", 0);
|
||||
}
|
||||
if (n_mru) {
|
||||
addLoader("LXMRU006", 0);
|
||||
}
|
||||
else {
|
||||
addLoader("LXMRU007", 0);
|
||||
}
|
||||
}
|
||||
else if (0x40==(ft->id & 0xF0)) {
|
||||
addLoader("LXUNF008", 0);
|
||||
}
|
||||
addLoader("LXUNF010", 0);
|
||||
}
|
||||
if (n_mru) {
|
||||
addLoader("LEXEC009", 0);
|
||||
addLoader("LEXEC009", NULL);
|
||||
}
|
||||
}
|
||||
addLoader("LEXEC010", 0);
|
||||
addLoader(getDecompressor(), 0);
|
||||
addLoader("LEXEC015", 0);
|
||||
addLoader("LEXEC010", NULL);
|
||||
linker->defineSymbol("filter_cto", ft->cto);
|
||||
linker->defineSymbol("filter_length",
|
||||
(ft->id & 0xf) % 3 == 0 ? ft->calls :
|
||||
ft->lastcall - ft->calls * 4);
|
||||
addLoader(getDecompressorSections(), NULL);
|
||||
addLoader("LEXEC015", NULL);
|
||||
if (ft->id) {
|
||||
if (ph.format==UPX_F_LINUX_ELF_i386) { // decompr, unfilter are separate
|
||||
if (0x80!=(ft->id & 0xF0)) {
|
||||
addLoader("LXUNF042", 0);
|
||||
}
|
||||
}
|
||||
else { // decompr, unfilter not separate
|
||||
{ // decompr, unfilter not separate
|
||||
if (0x80==(ft->id & 0xF0)) {
|
||||
addLoader("LEXEC110", 0);
|
||||
addLoader("LEXEC110", NULL);
|
||||
if (n_mru) {
|
||||
addLoader("LEXEC100", 0);
|
||||
addLoader("LEXEC100", NULL);
|
||||
}
|
||||
// bug in APP: jmp and label must be in same .asx/.asy
|
||||
addLoader("LEXEC016", 0);
|
||||
addLoader("LEXEC016", NULL);
|
||||
}
|
||||
}
|
||||
addFilter32(ft->id);
|
||||
if (ph.format==UPX_F_LINUX_ELF_i386) { // decompr, unfilter are separate
|
||||
if (0x80==(ft->id & 0xF0)) {
|
||||
if (0==n_mru) {
|
||||
addLoader("LXMRU058", 0);
|
||||
}
|
||||
}
|
||||
addLoader("LXUNF035", 0);
|
||||
}
|
||||
else { // decompr always unfilters
|
||||
addLoader("LEXEC017", 0);
|
||||
{ // decompr always unfilters
|
||||
addLoader("LEXEC017", NULL);
|
||||
}
|
||||
}
|
||||
|
||||
addLoader("IDENTSTR", 0);
|
||||
addLoader("LEXEC020", 0);
|
||||
addLoader("FOLDEXEC", 0);
|
||||
|
||||
char *ptr_cto = (char *)const_cast<unsigned char *>(getLoader());
|
||||
int sz_cto = getLoaderSize();
|
||||
if (0x20==(ft->id & 0xF0) || 0x30==(ft->id & 0xF0)) { // push byte '?' ; cto8
|
||||
patch_le16(ptr_cto, sz_cto, "\x6a?", 0x6a + (ft->cto << 8));
|
||||
checkPatch(NULL, 0, 0, 0); // reset
|
||||
else {
|
||||
addLoader("LEXEC017", NULL);
|
||||
}
|
||||
// PackHeader and overlay_offset at the end of the output file,
|
||||
// after the compressed data.
|
||||
|
||||
addLoader("IDENTSTR", NULL);
|
||||
addLoader("LEXEC020", NULL);
|
||||
addLoader("FOLDEXEC", NULL);
|
||||
freezeLoader();
|
||||
if (ph.method == M_LZMA) {
|
||||
const lzma_compress_result_t *res = &ph.compress_result.result_lzma;
|
||||
unsigned const properties = // lc, lp, pb, dummy
|
||||
(res->lit_context_bits << 0) |
|
||||
(res->lit_pos_bits << 8) |
|
||||
(res->pos_bits << 16);
|
||||
linker->defineSymbol("lzma_properties", properties);
|
||||
// -2 for properties
|
||||
linker->defineSymbol("lzma_c_len", ph.c_len - 2);
|
||||
linker->defineSymbol("lzma_u_len", ph.u_len);
|
||||
unsigned const stack = getDecompressorWrkmemSize();
|
||||
linker->defineSymbol("lzma_stack_adjust", 0u - stack);
|
||||
}
|
||||
if (0x80==(ft->id & 0xF0)) {
|
||||
int const mru = ft->n_mru ? 1+ ft->n_mru : 0;
|
||||
if (mru && mru!=256) {
|
||||
unsigned const is_pwr2 = (0==((mru -1) & mru));
|
||||
linker->defineSymbol("NMRU", mru - is_pwr2);
|
||||
}
|
||||
}
|
||||
linker->relocate();
|
||||
return getLoaderSize();
|
||||
}
|
||||
|
||||
@@ -369,22 +412,32 @@ PackLinuxI386::buildLoader(Filter const *ft)
|
||||
patch_le32(buf,sz_fold,"UPX3",progid);
|
||||
patch_le32(buf,sz_fold,"UPX2",exetype > 0 ? 0 : 0x7fffffff);
|
||||
|
||||
// get fresh filter
|
||||
Filter fold_ft = *ft;
|
||||
fold_ft.init(ft->id, ft->addvalue);
|
||||
int preferred_ctos[2] = {ft->cto, -1};
|
||||
fold_ft.preferred_ctos = preferred_ctos;
|
||||
|
||||
// filter
|
||||
optimizeFilter(&fold_ft, buf, sz_fold);
|
||||
bool success = fold_ft.filter(buf + sizeof(cprElfHdr2), sz_fold - sizeof(cprElfHdr2));
|
||||
(void)success;
|
||||
|
||||
return buildLinuxLoader(
|
||||
linux_i386exec_loader, sizeof(linux_i386exec_loader),
|
||||
buf, sz_fold, ft );
|
||||
}
|
||||
|
||||
int
|
||||
PackBSDI386::buildLoader(Filter const *ft)
|
||||
{
|
||||
unsigned const sz_fold = sizeof(bsd_i386exec_fold);
|
||||
MemBuffer buf(sz_fold);
|
||||
memcpy(buf, bsd_i386exec_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);
|
||||
|
||||
return buildLinuxLoader(
|
||||
bsd_i386exec_loader, sizeof(bsd_i386exec_loader),
|
||||
buf, sz_fold, ft );
|
||||
}
|
||||
|
||||
// FIXME: getLoaderPrefixSize is unused?
|
||||
int PackLinuxI386::getLoaderPrefixSize() const
|
||||
{
|
||||
return 116;
|
||||
@@ -396,7 +449,7 @@ int PackLinuxI386::getLoaderPrefixSize() const
|
||||
**************************************************************************/
|
||||
|
||||
// basic check of an Linux ELF Ehdr
|
||||
int PackLinuxI386::checkEhdr(const Elf_LE32_Ehdr *ehdr) const
|
||||
int PackLinuxI386::checkEhdr(const Elf32_Ehdr *ehdr) const
|
||||
{
|
||||
const unsigned char * const buf = ehdr->e_ident;
|
||||
|
||||
@@ -404,17 +457,18 @@ int PackLinuxI386::checkEhdr(const Elf_LE32_Ehdr *ehdr) const
|
||||
return -1;
|
||||
|
||||
// now check the ELF header
|
||||
if (!memcmp(buf+8, "FreeBSD", 7)) // branded
|
||||
if (!memcmp(buf+8, "FreeBSD", 7)) // branded
|
||||
return 1;
|
||||
if (ehdr->e_type != 2) // executable
|
||||
if (ehdr->e_type != Elf32_Ehdr::ET_EXEC
|
||||
&& ehdr->e_type != Elf32_Ehdr::ET_DYN ) // executable
|
||||
return 2;
|
||||
if (ehdr->e_machine != 3) // Intel 80386
|
||||
if (ehdr->e_machine != Elf32_Ehdr::EM_386) // Intel 80386
|
||||
return 3;
|
||||
if (ehdr->e_version != 1) // version
|
||||
if (ehdr->e_version != Elf32_Ehdr::EV_CURRENT) // version
|
||||
return 4;
|
||||
if (ehdr->e_phnum < 1)
|
||||
return 5;
|
||||
if (ehdr->e_phentsize != sizeof(Elf_LE32_Phdr))
|
||||
if (ehdr->e_phentsize != sizeof(Elf32_Phdr))
|
||||
return 6;
|
||||
|
||||
// check for Linux kernels
|
||||
@@ -435,19 +489,6 @@ int PackLinuxI386::checkEhdr(const Elf_LE32_Ehdr *ehdr) const
|
||||
}
|
||||
|
||||
|
||||
off_t PackLinuxI386::getbrk(const Elf_LE32_Phdr *phdr, int e_phnum) const
|
||||
{
|
||||
off_t brka = 0;
|
||||
for (int j = 0; j < e_phnum; ++phdr, ++j) {
|
||||
if (phdr->PT_LOAD == phdr->p_type) {
|
||||
off_t b = phdr->p_vaddr + phdr->p_memsz;
|
||||
if (b > brka)
|
||||
brka = b;
|
||||
}
|
||||
}
|
||||
return brka;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
@@ -458,9 +499,10 @@ bool PackLinuxI386::canPack()
|
||||
if (exetype != 0)
|
||||
return super::canPack();
|
||||
|
||||
Elf_LE32_Ehdr ehdr;
|
||||
Elf32_Ehdr ehdr;
|
||||
unsigned char *buf = ehdr.e_ident;
|
||||
|
||||
fi->seek(0, SEEK_SET);
|
||||
fi->readx(&ehdr, sizeof(ehdr));
|
||||
fi->seek(0, SEEK_SET);
|
||||
|
||||
@@ -468,12 +510,58 @@ bool PackLinuxI386::canPack()
|
||||
const unsigned l = get_le32(buf);
|
||||
|
||||
int elf = checkEhdr(&ehdr);
|
||||
if (elf >= 0)
|
||||
{
|
||||
if (elf >= 0) {
|
||||
// NOTE: ELF executables are now handled by p_lx_elf.cpp,
|
||||
// so we only handle them here if force_execve
|
||||
if (elf == 0 && opt->o_unix.force_execve)
|
||||
if (elf == 0 && opt->o_unix.force_execve) {
|
||||
exetype = 1;
|
||||
|
||||
unsigned osabi0 = ehdr.e_ident[Elf32_Ehdr::EI_OSABI];
|
||||
switch (osabi0) {
|
||||
case Elf32_Ehdr::ELFOSABI_LINUX:
|
||||
case Elf32_Ehdr::ELFOSABI_FREEBSD:
|
||||
case Elf32_Ehdr::ELFOSABI_NETBSD:
|
||||
case Elf32_Ehdr::ELFOSABI_OPENBSD:
|
||||
ei_osabi = osabi0; // Proudly declares its osabi in Ehdr.
|
||||
break;
|
||||
default:
|
||||
unsigned const e_phnum = get_native16(&ehdr.e_phnum);
|
||||
if (e_phnum<=(512/sizeof(Elf32_Phdr))) {
|
||||
char buf2[512];
|
||||
fi->seek(get_native32(&ehdr.e_phoff), SEEK_SET);
|
||||
fi->readx(buf2, sizeof(buf2));
|
||||
fi->seek(0, SEEK_SET);
|
||||
Elf32_Phdr const *phdr = (Elf32_Phdr const *)buf2;
|
||||
for (unsigned j=0; j < e_phnum; ++phdr, ++j) {
|
||||
if (phdr->PT_NOTE == get_native32(&phdr->p_type)) {
|
||||
unsigned const offset = get_native32(&phdr->p_offset);
|
||||
struct Elf32_Note note; memset(¬e, 0, sizeof(note));
|
||||
fi->seek(offset, SEEK_SET);
|
||||
fi->readx(¬e, sizeof(note));
|
||||
fi->seek(0, SEEK_SET);
|
||||
if (4==get_native32(¬e.descsz)
|
||||
&& 1==get_native32(¬e.type)
|
||||
&& 0==note.end ) {
|
||||
if (0==strcmp("NetBSD", (char const *)¬e.text)) {
|
||||
ei_osabi = Elf32_Ehdr::ELFOSABI_NETBSD;
|
||||
break;
|
||||
}
|
||||
if (0==strcmp("OpenBSD", (char const *)¬e.text)) {
|
||||
ei_osabi = Elf32_Ehdr::ELFOSABI_OPENBSD;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (UPX_F_BSD_i386==getFormat()
|
||||
&& !(Elf32_Ehdr::ELFOSABI_FREEBSD==ei_osabi
|
||||
|| Elf32_Ehdr::ELFOSABI_NETBSD ==ei_osabi
|
||||
|| Elf32_Ehdr::ELFOSABI_OPENBSD==ei_osabi )) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (l == 0x00640107 || l == 0x00640108 || l == 0x0064010b || l == 0x006400cc)
|
||||
{
|
||||
@@ -482,15 +570,17 @@ bool PackLinuxI386::canPack()
|
||||
// FIXME: N_TRSIZE, N_DRSIZE
|
||||
// FIXME: check for aout shared libraries
|
||||
}
|
||||
#if defined(__linux__)
|
||||
// only compress scripts when running under Linux
|
||||
else if (!memcmp(buf, "#!/", 3)) // #!/bin/sh
|
||||
exetype = -1;
|
||||
else if (!memcmp(buf, "#! /", 4)) // #! /bin/sh
|
||||
exetype = -1;
|
||||
else if (!memcmp(buf, "\xca\xfe\xba\xbe", 4)) // Java bytecode
|
||||
exetype = -2;
|
||||
#endif
|
||||
else { // shell scripts and other interpreters
|
||||
if (Elf32_Ehdr::ELFOSABI_LINUX!=ei_osabi) {
|
||||
return false; // so far, only Linux has runtime stub for shell
|
||||
}
|
||||
else if (!memcmp(buf, "#!/", 3)) // #!/bin/sh
|
||||
exetype = -1;
|
||||
else if (!memcmp(buf, "#! /", 4)) // #! /bin/sh
|
||||
exetype = -1;
|
||||
else if (!memcmp(buf, "\xca\xfe\xba\xbe", 4)) // Java bytecode
|
||||
exetype = -2;
|
||||
}
|
||||
|
||||
return super::canPack();
|
||||
}
|
||||
@@ -501,7 +591,7 @@ void PackLinuxI386::patchLoader() { }
|
||||
|
||||
void PackLinuxI386::patchLoaderChecksum()
|
||||
{
|
||||
unsigned char *const ptr = const_cast<unsigned char *>(getLoader());
|
||||
unsigned char *const ptr = getLoader();
|
||||
l_info *const lp = (l_info *)(sizeof(elfout.ehdr) +
|
||||
(elfout.ehdr.e_phnum * elfout.ehdr.e_phentsize) + (char *)&elfout );
|
||||
// checksum for loader + p_info
|
||||
|
||||
+43
-17
@@ -2,8 +2,8 @@
|
||||
|
||||
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) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -21,8 +21,11 @@
|
||||
If not, write to the Free Software Foundation, Inc.,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
markus@oberhumer.com ml1050@cdata.tvnet.hu
|
||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
||||
|
||||
John F. Reiser
|
||||
<jreiser@users.sourceforge.net>
|
||||
*/
|
||||
|
||||
|
||||
@@ -38,7 +41,7 @@ class PackLinuxI386 : public PackUnixLe32
|
||||
{
|
||||
typedef PackUnixLe32 super;
|
||||
public:
|
||||
PackLinuxI386(InputFile *f) : super(f) { }
|
||||
PackLinuxI386(InputFile *f);
|
||||
virtual void generateElfHdr(
|
||||
OutputFile *,
|
||||
void const *proto,
|
||||
@@ -59,6 +62,7 @@ protected:
|
||||
virtual void pack4(OutputFile *, Filter &); // append PackHeader
|
||||
|
||||
// loader util
|
||||
virtual Linker* newLinker() const;
|
||||
virtual int getLoaderPrefixSize() const;
|
||||
virtual int buildLinuxLoader(
|
||||
upx_byte const *const proto, // assembly-only sections
|
||||
@@ -74,8 +78,7 @@ protected:
|
||||
virtual void updateLoader(OutputFile *);
|
||||
|
||||
// ELF util
|
||||
virtual int checkEhdr(const Elf_LE32_Ehdr *ehdr) const;
|
||||
virtual off_t getbrk(const Elf_LE32_Phdr *phdr, int e_phnum) const;
|
||||
virtual int checkEhdr(const Elf32_Ehdr *ehdr) const;
|
||||
|
||||
enum {
|
||||
UPX_ELF_MAGIC = 0x5850557f // "\x7fUPX"
|
||||
@@ -84,31 +87,54 @@ protected:
|
||||
unsigned n_mru;
|
||||
|
||||
struct cprElfHdr1 {
|
||||
struct Elf_LE32_Ehdr ehdr;
|
||||
struct Elf_LE32_Phdr phdr[1];
|
||||
struct l_info linfo;
|
||||
Elf_LE32_Ehdr ehdr;
|
||||
Elf_LE32_Phdr phdr[1];
|
||||
l_info linfo;
|
||||
}
|
||||
__attribute_packed;
|
||||
|
||||
struct cprElfHdr2 {
|
||||
struct Elf_LE32_Ehdr ehdr;
|
||||
struct Elf_LE32_Phdr phdr[2];
|
||||
struct l_info linfo;
|
||||
Elf_LE32_Ehdr ehdr;
|
||||
Elf_LE32_Phdr phdr[2];
|
||||
l_info linfo;
|
||||
}
|
||||
__attribute_packed;
|
||||
|
||||
struct cprElfHdr3 {
|
||||
struct Elf_LE32_Ehdr ehdr;
|
||||
struct Elf_LE32_Phdr phdr[3];
|
||||
struct l_info linfo;
|
||||
Elf_LE32_Ehdr ehdr;
|
||||
Elf_LE32_Phdr phdr[3];
|
||||
l_info linfo;
|
||||
}
|
||||
__attribute_packed;
|
||||
|
||||
struct cprElfHdr3 elfout;
|
||||
cprElfHdr3 elfout;
|
||||
|
||||
struct Elf32_Note {
|
||||
unsigned namesz; // 8
|
||||
unsigned descsz; // 4
|
||||
unsigned type; // 1
|
||||
char text[0x18 - 4*4]; // "OpenBSD"
|
||||
unsigned end; // 0
|
||||
} elfnote;
|
||||
|
||||
unsigned char ei_osabi;
|
||||
char const *osabi_note;
|
||||
};
|
||||
|
||||
|
||||
class PackBSDI386 : public PackLinuxI386
|
||||
{
|
||||
typedef PackLinuxI386 super;
|
||||
public:
|
||||
PackBSDI386(InputFile *f);
|
||||
virtual int getFormat() const { return UPX_F_BSD_i386; }
|
||||
virtual const char *getName() const { return "*BSD/386"; }
|
||||
|
||||
protected:
|
||||
virtual void pack1(OutputFile *, Filter &); // generate executable header
|
||||
|
||||
virtual int buildLoader(const Filter *);
|
||||
};
|
||||
#endif /* already included */
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,311 @@
|
||||
/* p_lx_interp.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 "filter.h"
|
||||
#include "linker.h"
|
||||
#include "packer.h"
|
||||
#include "p_elf.h"
|
||||
#include "p_unix.h"
|
||||
#include "p_lx_exc.h"
|
||||
#include "p_lx_elf.h"
|
||||
#include "p_lx_interp.h"
|
||||
|
||||
#define PT_LOAD Elf32_Phdr::PT_LOAD
|
||||
#define PT_INTERP Elf32_Phdr::PT_INTERP
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
static const
|
||||
#include "stub/i386-linux.elf.interp-entry.h"
|
||||
static const
|
||||
#include "stub/i386-linux.elf.interp-fold.h"
|
||||
|
||||
PackLinuxElf32x86interp::PackLinuxElf32x86interp(InputFile *f) :
|
||||
super(f)
|
||||
{
|
||||
}
|
||||
|
||||
PackLinuxElf32x86interp::~PackLinuxElf32x86interp()
|
||||
{
|
||||
}
|
||||
|
||||
bool PackLinuxElf32x86interp::canPack()
|
||||
{
|
||||
if (opt->o_unix.make_ptinterp) {
|
||||
return true;
|
||||
}
|
||||
if (!opt->o_unix.use_ptinterp) {
|
||||
return false;
|
||||
}
|
||||
return super::canPack();
|
||||
}
|
||||
|
||||
void PackLinuxElf32x86interp::pack1(OutputFile *fo, Filter &)
|
||||
{
|
||||
fi->seek(0, SEEK_SET);
|
||||
fi->readx(&ehdri, sizeof(ehdri));
|
||||
assert(ehdri.e_phoff == sizeof(Elf32_Ehdr)); // checked by canPack()
|
||||
sz_phdrs = ehdri.e_phnum * ehdri.e_phentsize;
|
||||
|
||||
phdri = new Elf32_Phdr[(unsigned)ehdri.e_phnum];
|
||||
fi->seek(ehdri.e_phoff, SEEK_SET);
|
||||
fi->readx(phdri, sz_phdrs);
|
||||
|
||||
#define E Elf32_Ehdr
|
||||
cprElfHdr3 h3;
|
||||
memset(&h3, 0, sizeof(h3));
|
||||
memcpy(h3.ehdr.e_ident, "\177ELF", 4);
|
||||
h3.ehdr.e_ident[E::EI_CLASS] = E::ELFCLASS32;
|
||||
h3.ehdr.e_ident[E::EI_DATA] = E::ELFDATA2LSB;
|
||||
h3.ehdr.e_ident[E::EI_VERSION] = E::EV_CURRENT;
|
||||
h3.ehdr.e_ident[E::EI_OSABI] = E::ELFOSABI_LINUX;
|
||||
h3.ehdr.e_ident[E::EI_ABIVERSION] = E::EV_CURRENT;
|
||||
h3.ehdr.e_type = E::ET_EXEC;
|
||||
h3.ehdr.e_machine = E::EM_386;
|
||||
h3.ehdr.e_version = 1;
|
||||
h3.ehdr.e_phoff = sizeof(Elf32_Ehdr);
|
||||
h3.ehdr.e_ehsize = sizeof(Elf32_Ehdr);
|
||||
h3.ehdr.e_phentsize = sizeof(Elf32_Phdr);
|
||||
h3.ehdr.e_phnum = 3;
|
||||
h3.phdr[0].p_type = PT_LOAD;
|
||||
h3.phdr[0].p_flags = Elf32_Phdr::PF_X | Elf32_Phdr::PF_R;
|
||||
h3.phdr[0].p_align = 0x1000;
|
||||
h3.phdr[1].p_type = PT_LOAD;
|
||||
h3.phdr[1].p_flags = Elf32_Phdr::PF_W | Elf32_Phdr::PF_R;
|
||||
h3.phdr[1].p_align = 1;
|
||||
h3.phdr[2].p_type = PT_INTERP;
|
||||
h3.phdr[2].p_offset = (char *)&h3.phdr[2].p_vaddr - (char *)&h3;
|
||||
memcpy(&h3.phdr[2].p_vaddr, "/upxrun", h3.phdr[2].p_filesz = 8);
|
||||
h3.phdr[2].p_align = 1;
|
||||
|
||||
if (opt->o_unix.make_ptinterp) { // unusual "once per release"
|
||||
elfout = h3;
|
||||
elfout.ehdr.e_phnum = 1;
|
||||
fo->write(&elfout, elfout.ehdr.e_ehsize + elfout.ehdr.e_phentsize);
|
||||
}
|
||||
else { // usual case
|
||||
generateElfHdr(fo, &h3, getbrk(phdri, ehdri.e_phnum));
|
||||
}
|
||||
#undef E
|
||||
}
|
||||
|
||||
void PackLinuxElf32x86interp::pack2(OutputFile *fo, Filter &ft)
|
||||
{
|
||||
if (opt->o_unix.make_ptinterp) {
|
||||
return; // ignore current input file!
|
||||
}
|
||||
super::pack2(fo, ft);
|
||||
}
|
||||
|
||||
#undef PAGE_MASK
|
||||
#define PAGE_MASK (~0u<<12)
|
||||
|
||||
void PackLinuxElf32x86interp::pack3(OutputFile *fo, Filter &/*ft*/)
|
||||
{
|
||||
unsigned base = getbase(phdri, ehdri.e_phnum);
|
||||
unsigned sz = PAGE_MASK & (~PAGE_MASK + elfout.phdr[0].p_filesz);
|
||||
if (base < (0x11000 + sz)) {
|
||||
base = 0x11000 + sz;
|
||||
}
|
||||
if (opt->o_unix.make_ptinterp) {
|
||||
base = 0x10000;
|
||||
}
|
||||
elfout.phdr[0].p_paddr = elfout.phdr[0].p_vaddr = base - sz;
|
||||
if (opt->o_unix.make_ptinterp) {
|
||||
initLoader(linux_i386pti_loader, sizeof(linux_i386pti_loader));
|
||||
linker->addSection("FOLDEXEC", linux_i386pti_fold, sizeof(linux_i386pti_fold), 0);
|
||||
|
||||
addLoader("LXPTI000", NULL);
|
||||
|
||||
addLoader("LXPTI040", NULL);
|
||||
ph.method = M_NRV2B_LE32; addLoader(getDecompressorSections(), NULL);
|
||||
addLoader("LXPTI090", NULL);
|
||||
|
||||
addLoader("LXPTI041", NULL);
|
||||
ph.method = M_NRV2D_LE32; addLoader(getDecompressorSections(), NULL);
|
||||
addLoader("LXPTI090", NULL);
|
||||
|
||||
addLoader("LXPTI042", NULL);
|
||||
ph.method = M_NRV2E_LE32; addLoader(getDecompressorSections(), NULL);
|
||||
addLoader("LXPTI090", NULL);
|
||||
|
||||
addLoader("LXPTI043", NULL);
|
||||
ph.method = M_CL1B_LE32; addLoader(getDecompressorSections(), NULL);
|
||||
addLoader("LXPTI090", NULL);
|
||||
|
||||
addLoader("LXPTI091", NULL);
|
||||
|
||||
addLoader("LXPTI140", NULL);
|
||||
|
||||
addLoader("LXUNF002,LXUNF008,LXUNF010", NULL);
|
||||
addFilter32(0x46);
|
||||
addLoader("LXUNF042,LXUNF035", NULL);
|
||||
|
||||
addLoader("LXUNF002,LXUNF008,LXUNF010", NULL);
|
||||
addFilter32(0x49);
|
||||
addLoader("LXUNF042,LXUNF035", NULL);
|
||||
|
||||
addLoader("LXPTI200", NULL);
|
||||
addLoader("FOLDEXEC", NULL);
|
||||
freezeLoader();
|
||||
upx_byte const *p = getLoader();
|
||||
lsize = getLoaderSize();
|
||||
updateLoader(fo);
|
||||
fo->write(p, lsize);
|
||||
elfout.phdr[0].p_filesz = fo->getBytesWritten();
|
||||
}
|
||||
else {
|
||||
updateLoader(fo);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PackLinuxElf32x86interp::unpack(OutputFile *fo)
|
||||
{
|
||||
#define MAX_INTERP_HDR 512
|
||||
char bufehdr[MAX_INTERP_HDR];
|
||||
Elf32_Ehdr *const ehdr = (Elf32_Ehdr *)bufehdr;
|
||||
Elf32_Phdr const *phdr = (Elf32_Phdr *)(1+ehdr);
|
||||
|
||||
unsigned szb_info = sizeof(b_info);
|
||||
{
|
||||
fi->seek(0, SEEK_SET);
|
||||
fi->readx(bufehdr, MAX_INTERP_HDR);
|
||||
unsigned const e_entry = get_native32(&ehdr->e_entry);
|
||||
if (e_entry < 0x401180) { /* old style, 8-byte b_info */
|
||||
szb_info = 2*sizeof(unsigned);
|
||||
}
|
||||
}
|
||||
|
||||
fi->seek(overlay_offset, SEEK_SET);
|
||||
p_info hbuf;
|
||||
fi->readx(&hbuf, sizeof(hbuf));
|
||||
unsigned orig_file_size = get_native32(&hbuf.p_filesize);
|
||||
blocksize = get_native32(&hbuf.p_blocksize);
|
||||
if (file_size > (off_t)orig_file_size || blocksize > orig_file_size)
|
||||
throwCantUnpack("file header corrupted");
|
||||
|
||||
ibuf.alloc(blocksize + OVERHEAD);
|
||||
b_info bhdr; memset(&bhdr, 0, sizeof(bhdr));
|
||||
fi->readx(&bhdr, szb_info);
|
||||
ph.u_len = get_native32(&bhdr.sz_unc);
|
||||
ph.c_len = get_native32(&bhdr.sz_cpr);
|
||||
ph.filter_cto = bhdr.b_cto8;
|
||||
|
||||
// Uncompress Ehdr and Phdrs.
|
||||
fi->readx(ibuf, ph.c_len);
|
||||
decompress(ibuf, (upx_byte *)ehdr, false);
|
||||
|
||||
unsigned total_in = 0;
|
||||
unsigned total_out = 0;
|
||||
unsigned c_adler = upx_adler32(NULL, 0);
|
||||
unsigned u_adler = upx_adler32(NULL, 0);
|
||||
off_t ptload0hi=0, ptload1lo=0, ptload1sz=0;
|
||||
|
||||
// decompress PT_LOAD
|
||||
bool first_PF_X = true;
|
||||
fi->seek(- (off_t) (szb_info + ph.c_len), SEEK_CUR);
|
||||
for (unsigned j=0; j < ehdr->e_phnum; ++phdr, ++j) {
|
||||
if (PT_LOAD==phdr->p_type) {
|
||||
if (0==ptload0hi) {
|
||||
ptload0hi = phdr->p_filesz + phdr->p_offset;
|
||||
}
|
||||
else if (0==ptload1lo) {
|
||||
ptload1lo = phdr->p_offset;
|
||||
ptload1sz = phdr->p_filesz;
|
||||
}
|
||||
if (fo)
|
||||
fo->seek(phdr->p_offset, SEEK_SET);
|
||||
if (Elf32_Phdr::PF_X & phdr->p_flags) {
|
||||
unpackExtent(phdr->p_filesz, fo, total_in, total_out,
|
||||
c_adler, u_adler, first_PF_X, szb_info);
|
||||
first_PF_X = false;
|
||||
}
|
||||
else {
|
||||
unpackExtent(phdr->p_filesz, fo, total_in, total_out,
|
||||
c_adler, u_adler, false, szb_info);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (0!=ptload1sz && ptload0hi < ptload1lo) { // alignment hole?
|
||||
if (fo)
|
||||
fo->seek(ptload0hi, SEEK_SET);
|
||||
unpackExtent(ptload1lo - ptload0hi, fo, total_in, total_out,
|
||||
c_adler, u_adler, false, szb_info);
|
||||
}
|
||||
if (total_out != orig_file_size) { // non-PT_LOAD stuff
|
||||
if (fo)
|
||||
fo->seek(0, SEEK_END);
|
||||
unpackExtent(orig_file_size - total_out, fo, total_in, total_out,
|
||||
c_adler, u_adler, false, szb_info);
|
||||
}
|
||||
|
||||
// check for end-of-file
|
||||
fi->readx(&bhdr, szb_info);
|
||||
unsigned const sz_unc = ph.u_len = get_native32(&bhdr.sz_unc);
|
||||
|
||||
if (sz_unc == 0) { // uncompressed size 0 -> EOF
|
||||
// note: magic is always stored le32
|
||||
unsigned const sz_cpr = get_le32(&bhdr.sz_cpr);
|
||||
if (sz_cpr != UPX_MAGIC_LE32) // sz_cpr must be h->magic
|
||||
throwCompressedDataViolation();
|
||||
}
|
||||
else { // extra bytes after end?
|
||||
throwCompressedDataViolation();
|
||||
}
|
||||
|
||||
// update header with totals
|
||||
ph.c_len = total_in;
|
||||
ph.u_len = total_out;
|
||||
|
||||
// all bytes must be written
|
||||
if (total_out != orig_file_size)
|
||||
throwEOFException();
|
||||
|
||||
// finally test the checksums
|
||||
if (ph.c_adler != c_adler || ph.u_adler != u_adler)
|
||||
throwChecksumError();
|
||||
#undef MAX_INTERP_HDR
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
vi:ts=4:et
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
/* p_lx_interp.h --
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
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>
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __UPX_P_LX_INTERP_H //{
|
||||
#define __UPX_P_LX_INTERP_H
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// linux/interp386
|
||||
**************************************************************************/
|
||||
|
||||
class PackLinuxElf32x86interp : public PackLinuxElf32x86
|
||||
{
|
||||
typedef PackLinuxElf32x86 super;
|
||||
public:
|
||||
PackLinuxElf32x86interp(InputFile *f);
|
||||
virtual ~PackLinuxElf32x86interp();
|
||||
virtual int getVersion() const { return 13; }
|
||||
virtual int getFormat() const { return UPX_F_LINUX_ELFI_i386; }
|
||||
virtual const char *getName() const { return "linux/elfi386"; }
|
||||
|
||||
virtual bool canPack();
|
||||
virtual void unpack(OutputFile *fo);
|
||||
|
||||
protected:
|
||||
virtual void pack1(OutputFile *, Filter &); // generate executable header
|
||||
virtual void pack2(OutputFile *, Filter &); // append compressed data
|
||||
virtual void pack3(OutputFile *, Filter &); // build loader
|
||||
};
|
||||
|
||||
|
||||
#endif /*} already included */
|
||||
|
||||
|
||||
/*
|
||||
vi:ts=4:et
|
||||
*/
|
||||
|
||||
@@ -1,91 +0,0 @@
|
||||
/* p_lx_sep.cpp --
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2004 Laszlo Molnar
|
||||
Copyright (C) 2000-2004 John F. Reiser
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
and/or modify them under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING.
|
||||
If not, write to the Free Software Foundation, Inc.,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
Markus F.X.J. Oberhumer Laszlo Molnar John F. Reiser
|
||||
markus@oberhumer.com ml1050@cdata.tvnet.hu jreiser@BitWagon.com
|
||||
*/
|
||||
|
||||
|
||||
#include "conf.h"
|
||||
|
||||
#include "file.h"
|
||||
#include "packer.h"
|
||||
#include "p_elf.h"
|
||||
#include "p_unix.h"
|
||||
#include "p_lx_exc.h"
|
||||
#include "p_lx_elf.h"
|
||||
#include "p_lx_sep.h"
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
|
||||
//#define SCRIPT_SIZE (opt->o_unix.SCRIPT_MAX + sizeof(l_info))
|
||||
#define SCRIPT_SIZE (32 + sizeof(l_info))
|
||||
|
||||
const upx_byte *PackLinuxI386sep::getLoader() const
|
||||
{
|
||||
static char script[SCRIPT_SIZE];
|
||||
|
||||
memset(script, 0, sizeof(script));
|
||||
char const *name = opt->o_unix.script_name;
|
||||
if (0==name) {
|
||||
name = "/usr/local/lib/upxX";
|
||||
}
|
||||
upx_snprintf(script, sizeof(script), "#!%s\n", name);
|
||||
if (M_IS_NRV2B(ph.method)) {
|
||||
script[strlen(script)-2] = 'b';
|
||||
return (upx_byte const *)script;
|
||||
}
|
||||
if (M_IS_NRV2D(ph.method)) {
|
||||
script[strlen(script)-2] = 'd';
|
||||
return (upx_byte const *)script;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int PackLinuxI386sep::getLoaderSize() const
|
||||
{
|
||||
if (M_IS_NRV2B(ph.method))
|
||||
return SCRIPT_SIZE;
|
||||
if (M_IS_NRV2D(ph.method))
|
||||
return SCRIPT_SIZE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int PackLinuxI386sep::getLoaderPrefixSize() const
|
||||
{
|
||||
return opt->o_unix.SCRIPT_MAX;
|
||||
}
|
||||
|
||||
void PackLinuxI386sep::patchLoader()
|
||||
{
|
||||
patchLoaderChecksum();
|
||||
}
|
||||
|
||||
/*
|
||||
vi:ts=4:et
|
||||
*/
|
||||
|
||||
@@ -1,61 +0,0 @@
|
||||
/* p_lx_sep.h --
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2004 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2004 Laszlo Molnar
|
||||
Copyright (C) 2000-2004 John F. Reiser
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
and/or modify them under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING.
|
||||
If not, write to the Free Software Foundation, Inc.,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
Markus F.X.J. Oberhumer Laszlo Molnar John F. Reiser
|
||||
markus@oberhumer.com ml1050@cdata.tvnet.hu jreiser@BitWagon.com
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __UPX_P_LX_SEP_H //{
|
||||
#define __UPX_P_LX_SEP_H
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// linux/sep386
|
||||
**************************************************************************/
|
||||
|
||||
class PackLinuxI386sep : public PackLinuxI386elf
|
||||
{
|
||||
typedef PackLinuxI386elf super;
|
||||
public:
|
||||
PackLinuxI386sep(InputFile *f) : super(f) { }
|
||||
virtual int getFormat() const { return UPX_F_LINUX_SEP_i386; }
|
||||
virtual const char *getName() const { return "linux/sep386"; }
|
||||
|
||||
protected:
|
||||
virtual const upx_byte *getLoader() const;
|
||||
virtual int getLoaderSize() const;
|
||||
virtual int getLoaderPrefixSize() const;
|
||||
|
||||
virtual void patchLoader();
|
||||
virtual void updateLoader(OutputFile *) {}
|
||||
};
|
||||
|
||||
|
||||
#endif /*} already included */
|
||||
|
||||
/*
|
||||
vi:ts=4:et
|
||||
*/
|
||||
|
||||
+26
-8
@@ -2,9 +2,9 @@
|
||||
|
||||
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
|
||||
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
|
||||
@@ -22,8 +22,11 @@
|
||||
If not, write to the Free Software Foundation, Inc.,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
Markus F.X.J. Oberhumer Laszlo Molnar John F. Reiser
|
||||
markus@oberhumer.com ml1050@cdata.tvnet.hu jreiser@BitWagon.com
|
||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
||||
|
||||
John F. Reiser
|
||||
<jreiser@users.sourceforge.net>
|
||||
*/
|
||||
|
||||
|
||||
@@ -45,9 +48,9 @@
|
||||
**************************************************************************/
|
||||
|
||||
static const
|
||||
#include "stub/l_lx_sh86.h"
|
||||
#include "stub/i386-linux.elf.shell-entry.h"
|
||||
static const
|
||||
#include "stub/fold_sh86.h"
|
||||
#include "stub/i386-linux.elf.shell-fold.h"
|
||||
|
||||
|
||||
PackLinuxI386sh::PackLinuxI386sh(InputFile *f) :
|
||||
@@ -59,6 +62,15 @@ PackLinuxI386sh::~PackLinuxI386sh()
|
||||
{
|
||||
}
|
||||
|
||||
static unsigned
|
||||
umax(unsigned a, unsigned b)
|
||||
{
|
||||
if (a <= b) {
|
||||
return b;
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
int
|
||||
PackLinuxI386sh::buildLoader(Filter const *ft)
|
||||
{
|
||||
@@ -78,7 +90,13 @@ PackLinuxI386sh::buildLoader(Filter const *ft)
|
||||
|
||||
// filter
|
||||
optimizeFilter(&fold_ft, buf, sz_fold);
|
||||
bool success = fold_ft.filter(buf + sizeof(cprElfHdr2), sz_fold - sizeof(cprElfHdr2));
|
||||
unsigned fold_hdrlen = sizeof(l_info) + sizeof(Elf32_Ehdr) +
|
||||
sizeof(Elf32_Phdr) * get_native32(&((Elf32_Ehdr const *)(void *)buf)->e_phnum);
|
||||
if (0 == get_le32(fold_hdrlen + buf)) {
|
||||
// inconsistent SIZEOF_HEADERS in *.lds (ld, binutils)
|
||||
fold_hdrlen = umax(0x80, fold_hdrlen);
|
||||
}
|
||||
bool success = fold_ft.filter(buf + fold_hdrlen, sz_fold - fold_hdrlen);
|
||||
UNUSED(success);
|
||||
|
||||
return buildLinuxLoader(
|
||||
|
||||
+8
-5
@@ -2,9 +2,9 @@
|
||||
|
||||
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
|
||||
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
|
||||
@@ -22,8 +22,11 @@
|
||||
If not, write to the Free Software Foundation, Inc.,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
Markus F.X.J. Oberhumer Laszlo Molnar John F. Reiser
|
||||
markus@oberhumer.com ml1050@cdata.tvnet.hu jreiser@BitWagon.com
|
||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
<mfx@users.sourceforge.net> <ml1050@users.sourceforge.net>
|
||||
|
||||
John F. Reiser
|
||||
<jreiser@users.sourceforge.net>
|
||||
*/
|
||||
|
||||
|
||||
|
||||
+469
@@ -0,0 +1,469 @@
|
||||
/* p_mach.cpp -- pack Mach Object executable
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 2004-2006 John Reiser
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
and/or modify them under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING.
|
||||
If not, write to the Free Software Foundation, Inc.,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
John Reiser
|
||||
jreiser@users.sourceforge.net
|
||||
*/
|
||||
|
||||
|
||||
#include "conf.h"
|
||||
|
||||
#include "file.h"
|
||||
#include "filter.h"
|
||||
#include "linker.h"
|
||||
#include "packer.h"
|
||||
#include "p_mach.h"
|
||||
#include "ui.h"
|
||||
|
||||
static const
|
||||
#include "stub/powerpc-darwin.macho-entry.h"
|
||||
static const
|
||||
#include "stub/powerpc-darwin.macho-fold.h"
|
||||
|
||||
PackMachPPC32::PackMachPPC32(InputFile *f) :
|
||||
super(f), n_segment(0), rawmseg(0), msegcmd(0)
|
||||
{
|
||||
}
|
||||
|
||||
PackMachPPC32::~PackMachPPC32()
|
||||
{
|
||||
delete [] msegcmd;
|
||||
delete [] rawmseg;
|
||||
}
|
||||
|
||||
const int *PackMachPPC32::getCompressionMethods(int /*method*/, int /*level*/) const
|
||||
{
|
||||
// There really is no LE bias in M_NRV2E_LE32.
|
||||
static const int m_nrv2e[] = { M_NRV2E_LE32, -1 };
|
||||
return m_nrv2e;
|
||||
}
|
||||
|
||||
|
||||
const int *PackMachPPC32::getFilters() const
|
||||
{
|
||||
static const int filters[] = { 0xd0, -1 };
|
||||
return filters;
|
||||
}
|
||||
|
||||
Linker *PackMachPPC32::newLinker() const
|
||||
{
|
||||
return new ElfLinkerPpc32;
|
||||
}
|
||||
|
||||
void
|
||||
PackMachPPC32::addStubEntrySections(Filter const *)
|
||||
{
|
||||
addLoader("MACOS000", NULL);
|
||||
//addLoader(getDecompressorSections(), NULL);
|
||||
addLoader(
|
||||
( M_IS_NRV2E(ph.method) ? "NRV_HEAD,NRV2E,NRV_TAIL"
|
||||
: M_IS_NRV2D(ph.method) ? "NRV_HEAD,NRV2D,NRV_TAIL"
|
||||
: M_IS_NRV2B(ph.method) ? "NRV_HEAD,NRV2B,NRV_TAIL"
|
||||
: M_IS_LZMA(ph.method) ? "LZMA_ELF00,LZMA_DEC20,LZMA_DEC30"
|
||||
: NULL), NULL);
|
||||
addLoader("ELFMAINY,IDENTSTR,+40,ELFMAINZ,FOLDEXEC", NULL);
|
||||
}
|
||||
|
||||
|
||||
void PackMachPPC32::defineSymbols(Filter const *)
|
||||
{
|
||||
// empty
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
PackMachPPC32::buildMachLoader(
|
||||
upx_byte const *const proto,
|
||||
unsigned const szproto,
|
||||
upx_byte const *const fold,
|
||||
unsigned const szfold,
|
||||
Filter const *ft
|
||||
)
|
||||
{
|
||||
initLoader(proto, szproto);
|
||||
|
||||
struct b_info h; memset(&h, 0, sizeof(h));
|
||||
unsigned fold_hdrlen = 0;
|
||||
if (0 < szfold) {
|
||||
h.sz_unc = (szfold < fold_hdrlen) ? 0 : (szfold - fold_hdrlen);
|
||||
h.b_method = (unsigned char) ph.method;
|
||||
h.b_ftid = (unsigned char) ph.filter;
|
||||
h.b_cto8 = (unsigned char) ph.filter_cto;
|
||||
}
|
||||
unsigned char const *const uncLoader = fold_hdrlen + fold;
|
||||
|
||||
unsigned char *const cprLoader = new unsigned char[sizeof(h) + h.sz_unc];
|
||||
if (0 < szfold) {
|
||||
unsigned sz_cpr = 0;
|
||||
int r = upx_compress(uncLoader, h.sz_unc, sizeof(h) + cprLoader, &sz_cpr,
|
||||
NULL, ph.method, 10, NULL, NULL );
|
||||
h.sz_cpr = sz_cpr;
|
||||
if (r != UPX_E_OK || h.sz_cpr >= h.sz_unc)
|
||||
throwInternalError("loader compression failed");
|
||||
}
|
||||
memcpy(cprLoader, &h, sizeof(h));
|
||||
|
||||
// This adds the definition to the "library", to be used later.
|
||||
linker->addSection("FOLDEXEC", cprLoader, sizeof(h) + h.sz_cpr, 0);
|
||||
delete [] cprLoader;
|
||||
|
||||
int const GAP = 128; // must match stub/l_mac_ppc.S
|
||||
segcmdo.vmsize += h.sz_unc - h.sz_cpr + GAP + 64;
|
||||
|
||||
addStubEntrySections(ft);
|
||||
|
||||
freezeLoader();
|
||||
defineSymbols(ft);
|
||||
linker->relocate();
|
||||
return getLoaderSize();
|
||||
}
|
||||
|
||||
int
|
||||
PackMachPPC32::buildLoader(const Filter *ft)
|
||||
{
|
||||
return buildMachLoader(
|
||||
l_mac_ppc32_loader, sizeof(l_mac_ppc32_loader),
|
||||
fold_machppc32, sizeof(fold_machppc32), ft );
|
||||
}
|
||||
void PackMachPPC32::patchLoader() { }
|
||||
void PackMachPPC32::updateLoader(OutputFile *) {}
|
||||
|
||||
void
|
||||
PackMachPPC32::patchLoaderChecksum()
|
||||
{
|
||||
unsigned char *const ptr = getLoader();
|
||||
l_info *const lp = &linfo;
|
||||
// checksum for loader; also some PackHeader info
|
||||
lp->l_checksum = 0;
|
||||
lp->l_magic = UPX_MAGIC_LE32; // LE32 always
|
||||
lp->l_lsize = (unsigned short) lsize;
|
||||
lp->l_version = (unsigned char) ph.version;
|
||||
lp->l_format = (unsigned char) ph.format;
|
||||
// INFO: lp->l_checksum is currently unused
|
||||
lp->l_checksum = upx_adler32(ptr, lsize);
|
||||
}
|
||||
|
||||
static int __acc_cdecl_qsort
|
||||
compare_segment_command(void const *const aa, void const *const bb)
|
||||
{
|
||||
Mach_segment_command const *const a = (Mach_segment_command const *)aa;
|
||||
Mach_segment_command const *const b = (Mach_segment_command const *)bb;
|
||||
unsigned const xa = a->cmd - Mach_segment_command::LC_SEGMENT;
|
||||
unsigned const xb = b->cmd - Mach_segment_command::LC_SEGMENT;
|
||||
if (xa < xb) return -1; // LC_SEGMENT first
|
||||
if (xa > xb) return 1;
|
||||
if (a->vmaddr < b->vmaddr) return -1; // ascending by .vmaddr
|
||||
if (a->vmaddr > b->vmaddr) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
PackMachPPC32::pack4(OutputFile *fo, Filter &ft) // append PackHeader
|
||||
{
|
||||
// offset of p_info in compressed file
|
||||
overlay_offset = sizeof(mhdro) + sizeof(segcmdo) + sizeof(threado) + sizeof(linfo);
|
||||
|
||||
super::pack4(fo, ft);
|
||||
segcmdo.filesize = fo->getBytesWritten();
|
||||
segcmdo.vmsize += segcmdo.filesize;
|
||||
fo->seek(sizeof(mhdro), SEEK_SET);
|
||||
fo->write(&segcmdo, sizeof(segcmdo));
|
||||
fo->write(&threado, sizeof(threado));
|
||||
fo->write(&linfo, sizeof(linfo));
|
||||
}
|
||||
|
||||
void
|
||||
PackMachPPC32::pack3(OutputFile *fo, Filter &ft) // append loader
|
||||
{
|
||||
BE32 disp;
|
||||
unsigned const zero = 0;
|
||||
unsigned len = fo->getBytesWritten();
|
||||
fo->write(&zero, 3& -len);
|
||||
len += (3& -len) + sizeof(disp);
|
||||
set_be32(&disp, 4+ len - sz_mach_headers); // 4: sizeof(instruction)
|
||||
fo->write(&disp, sizeof(disp));
|
||||
|
||||
threado.state.srr0 = len + segcmdo.vmaddr; /* entry address */
|
||||
super::pack3(fo, ft);
|
||||
}
|
||||
|
||||
// Determine length of gap between PT_LOAD phdri[k] and closest PT_LOAD
|
||||
// which follows in the file (or end-of-file). Optimize for common case
|
||||
// where the PT_LOAD are adjacent ascending by .p_offset. Assume no overlap.
|
||||
|
||||
unsigned PackMachPPC32::find_SEGMENT_gap(
|
||||
unsigned const k
|
||||
)
|
||||
{
|
||||
if (Mach_segment_command::LC_SEGMENT!=msegcmd[k].cmd
|
||||
|| 0==msegcmd[k].filesize ) {
|
||||
return 0;
|
||||
}
|
||||
unsigned const hi = get_native32(&msegcmd[k].fileoff) +
|
||||
get_native32(&msegcmd[k].filesize);
|
||||
unsigned lo = ph.u_file_size;
|
||||
unsigned j = k;
|
||||
for (;;) { // circular search, optimize for adjacent ascending
|
||||
++j;
|
||||
if (n_segment==j) {
|
||||
j = 0;
|
||||
}
|
||||
if (k==j) {
|
||||
break;
|
||||
}
|
||||
if (Mach_segment_command::LC_SEGMENT==msegcmd[j].cmd
|
||||
&& 0!=msegcmd[j].filesize ) {
|
||||
unsigned const t = get_native32(&msegcmd[j].fileoff);
|
||||
if ((t - hi) < (lo - hi)) {
|
||||
lo = t;
|
||||
if (hi==lo) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return lo - hi;
|
||||
}
|
||||
|
||||
void
|
||||
PackMachPPC32::pack2(OutputFile *fo, Filter &ft) // append compressed body
|
||||
{
|
||||
Extent x;
|
||||
unsigned k;
|
||||
|
||||
// count passes, set ptload vars
|
||||
uip->ui_total_passes = 0;
|
||||
for (k = 0; k < n_segment; ++k) {
|
||||
if (Mach_segment_command::LC_SEGMENT==msegcmd[k].cmd
|
||||
&& 0!=msegcmd[k].filesize ) {
|
||||
uip->ui_total_passes++;
|
||||
if (find_SEGMENT_gap(k)) {
|
||||
uip->ui_total_passes++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// compress extents
|
||||
unsigned total_in = 0;
|
||||
unsigned total_out = 0;
|
||||
|
||||
unsigned hdr_u_len = mhdri.sizeofcmds;
|
||||
|
||||
uip->ui_pass = 0;
|
||||
ft.addvalue = 0;
|
||||
|
||||
int nx = 0;
|
||||
for (k = 0; k < n_segment; ++k)
|
||||
if (Mach_segment_command::LC_SEGMENT==msegcmd[k].cmd
|
||||
&& 0!=msegcmd[k].filesize ) {
|
||||
x.offset = msegcmd[k].fileoff;
|
||||
x.size = msegcmd[k].filesize;
|
||||
if (0 == nx) { // 1st LC_SEGMENT must cover Mach_header at 0==fileoffset
|
||||
unsigned const delta = mhdri.sizeofcmds;
|
||||
x.offset += delta;
|
||||
x.size -= delta;
|
||||
}
|
||||
packExtent(x, total_in, total_out,
|
||||
((Mach_segment_command::VM_PROT_EXECUTE & msegcmd[k].initprot)
|
||||
? &ft : 0 ), fo, hdr_u_len );
|
||||
hdr_u_len = 0;
|
||||
++nx;
|
||||
}
|
||||
for (k = 0; k < n_segment; ++k) {
|
||||
x.size = find_SEGMENT_gap(k);
|
||||
if (x.size) {
|
||||
x.offset = get_native32(&msegcmd[k].fileoff) +
|
||||
get_native32(&msegcmd[k].filesize);
|
||||
packExtent(x, total_in, total_out, 0, fo);
|
||||
}
|
||||
}
|
||||
|
||||
if ((off_t)total_in != file_size)
|
||||
throwEOFException();
|
||||
segcmdo.filesize = fo->getBytesWritten();
|
||||
}
|
||||
|
||||
#undef PAGE_MASK
|
||||
#undef PAGE_SIZE
|
||||
#define PAGE_MASK (~0u<<12)
|
||||
#define PAGE_SIZE -PAGE_MASK
|
||||
void
|
||||
PackMachPPC32::pack1(OutputFile *fo, Filter &/*ft*/) // generate executable header
|
||||
{
|
||||
mhdro = mhdri;
|
||||
mhdro.ncmds = 2;
|
||||
mhdro.sizeofcmds = sizeof(segcmdo) + sizeof(threado);
|
||||
mhdro.flags = Mach_header::MH_NOUNDEFS;
|
||||
fo->write(&mhdro, sizeof(mhdro));
|
||||
|
||||
segcmdo.cmd = Mach_segment_command::LC_SEGMENT;
|
||||
segcmdo.cmdsize = sizeof(segcmdo);
|
||||
strncpy((char *)&segcmdo.segname, "__TEXT", sizeof(segcmdo.segname));
|
||||
segcmdo.vmaddr = PAGE_MASK & (~PAGE_MASK +
|
||||
msegcmd[n_segment -1].vmsize + msegcmd[n_segment -1].vmaddr );
|
||||
segcmdo.vmsize = 0; // adjust later
|
||||
segcmdo.fileoff = 0;
|
||||
segcmdo.filesize = 0; // adjust later
|
||||
segcmdo.initprot = segcmdo.maxprot =
|
||||
Mach_segment_command::VM_PROT_READ |
|
||||
Mach_segment_command::VM_PROT_WRITE |
|
||||
Mach_segment_command::VM_PROT_EXECUTE;
|
||||
segcmdo.nsects = 0;
|
||||
segcmdo.flags = 0;
|
||||
fo->write(&segcmdo, sizeof(segcmdo));
|
||||
|
||||
threado.cmd = Mach_segment_command::LC_UNIXTHREAD;
|
||||
threado.cmdsize = sizeof(threado);
|
||||
threado.flavor = Mach_thread_command::PPC_THREAD_STATE;
|
||||
threado.count = Mach_thread_command::PPC_THREAD_STATE_COUNT;
|
||||
memset(&threado.state, 0, sizeof(threado.state));
|
||||
fo->write(&threado, sizeof(threado));
|
||||
sz_mach_headers = fo->getBytesWritten();
|
||||
|
||||
memset((char *)&linfo, 0, sizeof(linfo));
|
||||
fo->write(&linfo, sizeof(linfo));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
PackMachPPC32::unpack(OutputFile *fo)
|
||||
{
|
||||
fi->seek(overlay_offset, SEEK_SET);
|
||||
p_info hbuf;
|
||||
fi->readx(&hbuf, sizeof(hbuf));
|
||||
unsigned orig_file_size = get_native32(&hbuf.p_filesize);
|
||||
blocksize = get_native32(&hbuf.p_blocksize);
|
||||
if (file_size > (off_t)orig_file_size || blocksize > orig_file_size)
|
||||
throwCantUnpack("file header corrupted");
|
||||
|
||||
ibuf.alloc(blocksize + OVERHEAD);
|
||||
b_info bhdr; memset(&bhdr, 0, sizeof(bhdr));
|
||||
fi->readx(&bhdr, sizeof(bhdr));
|
||||
ph.u_len = get_native32(&bhdr.sz_unc);
|
||||
ph.c_len = get_native32(&bhdr.sz_cpr);
|
||||
ph.filter_cto = bhdr.b_cto8;
|
||||
|
||||
// Uncompress Macho headers
|
||||
fi->readx(ibuf, ph.c_len);
|
||||
Mach_header *const mhdr = (Mach_header *)new upx_byte[ph.u_len];
|
||||
decompress(ibuf, (upx_byte *)mhdr, false);
|
||||
unsigned const ncmds = mhdr->ncmds;
|
||||
|
||||
msegcmd = new Mach_segment_command[ncmds];
|
||||
unsigned char *ptr = (unsigned char *)(1+mhdr);
|
||||
for (unsigned j= 0; j < ncmds; ++j) {
|
||||
msegcmd[j] = *(Mach_segment_command *)ptr;
|
||||
ptr += (unsigned) ((Mach_segment_command *)ptr)->cmdsize;
|
||||
}
|
||||
|
||||
// Put LC_SEGMENT together at the beginning, ascending by .vmaddr.
|
||||
qsort(msegcmd, ncmds, sizeof(*msegcmd), compare_segment_command);
|
||||
n_segment = 0;
|
||||
for (unsigned j= 0; j < ncmds; ++j) {
|
||||
n_segment += (Mach_segment_command::LC_SEGMENT==msegcmd[j].cmd);
|
||||
}
|
||||
|
||||
unsigned total_in = 0;
|
||||
unsigned total_out = 0;
|
||||
unsigned c_adler = upx_adler32(NULL, 0);
|
||||
unsigned u_adler = upx_adler32(NULL, 0);
|
||||
Mach_segment_command const *sc = (Mach_segment_command const *)(1+ mhdr);
|
||||
unsigned k;
|
||||
|
||||
fi->seek(- (off_t)(sizeof(bhdr) + ph.c_len), SEEK_CUR);
|
||||
for (
|
||||
k = 0;
|
||||
k < ncmds;
|
||||
(++k), (sc = (Mach_segment_command const *)(sc->cmdsize + (char const *)sc))
|
||||
) {
|
||||
if (Mach_segment_command::LC_SEGMENT==sc->cmd
|
||||
&& 0!=sc->filesize ) {
|
||||
unsigned filesize = get_be32(&sc->filesize);
|
||||
unpackExtent(filesize, fo, total_in, total_out, c_adler, u_adler, false, sizeof(bhdr));
|
||||
}
|
||||
}
|
||||
for (unsigned j = 0; j < ncmds; ++j) {
|
||||
unsigned const size = find_SEGMENT_gap(j);
|
||||
if (size) {
|
||||
unsigned const where = get_native32(&msegcmd[k].fileoff) +
|
||||
get_native32(&msegcmd[k].filesize);
|
||||
if (fo)
|
||||
fo->seek(where, SEEK_SET);
|
||||
unpackExtent(size, fo, total_in, total_out,
|
||||
c_adler, u_adler, false, sizeof(bhdr));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
PackMachPPC32::canPack()
|
||||
{
|
||||
fi->seek(0, SEEK_SET);
|
||||
fi->readx(&mhdri, sizeof(mhdri));
|
||||
|
||||
if (Mach_header::MH_MAGIC !=mhdri.magic
|
||||
|| Mach_header::CPU_TYPE_POWERPC !=mhdri.cputype
|
||||
|| Mach_header::MH_EXECUTE !=mhdri.filetype
|
||||
)
|
||||
return false;
|
||||
|
||||
rawmseg = (Mach_segment_command *)new char[mhdri.sizeofcmds];
|
||||
fi->readx(rawmseg, mhdri.sizeofcmds);
|
||||
|
||||
msegcmd = new Mach_segment_command[mhdri.ncmds];
|
||||
unsigned char *ptr = (unsigned char *)rawmseg;
|
||||
for (unsigned j= 0; j < mhdri.ncmds; ++j) {
|
||||
msegcmd[j] = *(Mach_segment_command *)ptr;
|
||||
ptr += (unsigned) ((Mach_segment_command *)ptr)->cmdsize;
|
||||
}
|
||||
|
||||
|
||||
// Put LC_SEGMENT together at the beginning, ascending by .vmaddr.
|
||||
qsort(msegcmd, mhdri.ncmds, sizeof(*msegcmd), compare_segment_command);
|
||||
|
||||
// Check that LC_SEGMENTs form one contiguous chunk of the file.
|
||||
for (unsigned j= 0; j < mhdri.ncmds; ++j) {
|
||||
if (Mach_segment_command::LC_SEGMENT==msegcmd[j].cmd) {
|
||||
if (0xfff & (msegcmd[j].fileoff | msegcmd[j].vmaddr)) {
|
||||
return false;
|
||||
}
|
||||
if (0 < j) {
|
||||
unsigned const sz = ~0xfff
|
||||
& (0xfff + msegcmd[j-1].filesize);
|
||||
if ((sz + msegcmd[j-1].fileoff)!=msegcmd[j].fileoff) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
++n_segment;
|
||||
sz_segment = msegcmd[j].filesize + msegcmd[j].fileoff - msegcmd[0].fileoff;
|
||||
}
|
||||
}
|
||||
// set options
|
||||
opt->o_unix.blocksize = file_size;
|
||||
return 0 < n_segment;
|
||||
}
|
||||
|
||||
/*
|
||||
vi:ts=4:et
|
||||
*/
|
||||
+217
@@ -0,0 +1,217 @@
|
||||
/* p_mach.h --
|
||||
|
||||
This file is part of the UPX executable compressor.
|
||||
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
and/or modify them under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; see the file COPYING.
|
||||
If not, write to the Free Software Foundation, Inc.,
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
markus@oberhumer.com ml1050@users.sourceforge.net
|
||||
*/
|
||||
|
||||
|
||||
#ifndef __UPX_P_MACHO_H
|
||||
#define __UPX_P_MACHO_H
|
||||
|
||||
/*************************************************************************
|
||||
// Mach Mach Object executable
|
||||
**************************************************************************/
|
||||
|
||||
struct Mach_header {
|
||||
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 {
|
||||
BE32 cmd;
|
||||
enum {
|
||||
LC_SEGMENT = 0x1,
|
||||
LC_THREAD = 0x4,
|
||||
LC_UNIXTHREAD = 0x5,
|
||||
LC_LOAD_DYLINKER = 0xe
|
||||
};
|
||||
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 {
|
||||
BE32 cmd; /* LC_THREAD or LC_UNIXTHREAD */
|
||||
BE32 cmdsize; /* total size of this command */
|
||||
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;
|
||||
|
||||
|
||||
#include "p_unix.h"
|
||||
|
||||
|
||||
class PackMachPPC32 : public PackUnixBe32
|
||||
{
|
||||
typedef PackUnixBe32 super;
|
||||
public:
|
||||
PackMachPPC32(InputFile *f);
|
||||
virtual ~PackMachPPC32();
|
||||
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 *getFilters() const;
|
||||
|
||||
// called by the generic pack()
|
||||
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 PackHeader
|
||||
|
||||
virtual void unpack(OutputFile *fo);
|
||||
|
||||
virtual bool canPack();
|
||||
virtual unsigned find_SEGMENT_gap(unsigned const k);
|
||||
|
||||
protected:
|
||||
virtual int buildLoader(const Filter *ft);
|
||||
virtual Linker* newLinker() const;
|
||||
virtual void patchLoader();
|
||||
virtual void patchLoaderChecksum();
|
||||
virtual void updateLoader(OutputFile *);
|
||||
virtual int buildMachLoader(
|
||||
upx_byte const *const proto,
|
||||
unsigned const szproto,
|
||||
upx_byte const *const fold,
|
||||
unsigned const szfold,
|
||||
Filter const *ft );
|
||||
virtual void defineSymbols(Filter const *);
|
||||
virtual void addStubEntrySections(Filter const *);
|
||||
|
||||
unsigned n_segment;
|
||||
unsigned sz_segment;
|
||||
unsigned sz_mach_headers;
|
||||
Mach_segment_command *rawmseg; // as input, with sections
|
||||
Mach_segment_command *msegcmd; // LC_SEGMENT first, without sections
|
||||
Mach_header mhdri;
|
||||
|
||||
Mach_header mhdro;
|
||||
Mach_segment_command segcmdo;
|
||||
Mach_thread_command threado;
|
||||
struct l_info linfo;
|
||||
};
|
||||
|
||||
|
||||
#endif /* already included */
|
||||
|
||||
|
||||
/*
|
||||
vi:ts=4:et
|
||||
*/
|
||||
|
||||
+422
-183
@@ -2,9 +2,9 @@
|
||||
|
||||
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) 2002-2004 Jens Medoch
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
Copyright (C) 2002-2006 Jens Medoch
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -35,31 +35,31 @@
|
||||
#include "filter.h"
|
||||
#include "packer.h"
|
||||
#include "p_ps1.h"
|
||||
#include "linker.h"
|
||||
|
||||
static const
|
||||
#include "stub/l_ps1b.h"
|
||||
static const
|
||||
#include "stub/l_ps1c.h"
|
||||
#include "stub/mipsel.r3000-ps1.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 MIPS_LO(a) ((a) & 0xffff)
|
||||
#define MIPS_JP(a) ((0x08 << 24) | (((a) & 0x0fffffff) >> 2))
|
||||
#define TIL_ALIGNED(a,b) (((b) - ((a) & ((b) - 1))) & (b) - 1)
|
||||
#define SZ_IH_BKUP (10 * sizeof(LE32))
|
||||
#define HD_CODE_OFS (sizeof(ps1_exe_t) + sz_cbh)
|
||||
|
||||
#define CD_SEC 2048
|
||||
#define PS_HDR_SIZE CD_SEC
|
||||
#define PS_RAM_SIZE 0x200000
|
||||
#define PS_MIN_SIZE (PS_HDR_SIZE*3)
|
||||
#define PS_MAX_SIZE 0x1e8000
|
||||
|
||||
#define SZ_IH_BKUP (10 * sizeof(LE32))
|
||||
#define HD_CODE_OFS (sizeof(ps1_exe_t))
|
||||
|
||||
#define K0_BS (0x80000000)
|
||||
#define K1_BS (0xa0000000)
|
||||
#define FIX_PSVR (K1_BS - (ih.epc & K0_BS)) + (PS_HDR_SIZE - HD_CODE_OFS)
|
||||
#define K0_BS (0x80000000)
|
||||
#define K1_BS (0xa0000000)
|
||||
#define EXE_BS (ih.epc & K0_BS)
|
||||
#define FIX_PSVR (K1_BS - EXE_BS) + (PS_HDR_SIZE - HD_CODE_OFS)
|
||||
|
||||
// lui / addiu
|
||||
#define MIPS_HI(a) (((a) >> 16) + (((a) & 0x8000) >> 15))
|
||||
#define MIPS_LO(a) ((a) & 0xffff)
|
||||
#define MIPS_PC16(a) ((a) >> 2)
|
||||
#define MIPS_PC26(a) (((a) & 0x0fffffff) >> 2)
|
||||
|
||||
/*************************************************************************
|
||||
// ps1 exe looks like this:
|
||||
@@ -77,22 +77,24 @@ static const
|
||||
|
||||
PackPs1::PackPs1(InputFile *f) :
|
||||
super(f),
|
||||
isCon(true^opt->ps1_exe.boot_only), is32Bit(true^opt->ps1_exe.do_8bit),
|
||||
overlap(0), sa_cnt(0)
|
||||
isCon(!opt->ps1_exe.boot_only), is32Bit(!opt->ps1_exe.do_8bit),
|
||||
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);
|
||||
COMPILE_TIME_ASSERT(sizeof(ps1_exe_t) == 136);
|
||||
COMPILE_TIME_ASSERT(sizeof(ps1_exe_hb_t) == 44);
|
||||
COMPILE_TIME_ASSERT(sizeof(ps1_exe_chb_t) == 5);
|
||||
|
||||
COMPILE_TIME_ASSERT(PS_HDR_SIZE > sizeof(ps1_exe_t));
|
||||
COMPILE_TIME_ASSERT(SZ_IH_BKUP == 40);
|
||||
#if 1 || defined(WITH_NRV)
|
||||
COMPILE_TIME_ASSERT(sizeof(nrv_boot_loader) == 3918);
|
||||
COMPILE_TIME_ASSERT(NRV_BOOT_LOADER_CRC32 == 0xdf0cbd9e);
|
||||
COMPILE_TIME_ASSERT(sizeof(nrv_con_loader) == 2810);
|
||||
COMPILE_TIME_ASSERT(NRV_CON_LOADER_CRC32 == 0x31747f8b);
|
||||
#if 0 // 1 || defined(WITH_NRV)
|
||||
COMPILE_TIME_ASSERT(sizeof(nrv_loader) == 14812);
|
||||
COMPILE_TIME_ASSERT(NRV_BOOT_LOADER_CRC32 == 0x0);
|
||||
#endif
|
||||
fdata_size = file_size - PS_HDR_SIZE;
|
||||
ram_size = !opt->ps1_exe.do_8mb ? 0x200000 : 0x800000;
|
||||
}
|
||||
|
||||
|
||||
const int *PackPs1::getCompressionMethods(int method, int level) const
|
||||
{
|
||||
if (is32Bit)
|
||||
@@ -101,12 +103,40 @@ const int *PackPs1::getCompressionMethods(int method, int level) const
|
||||
return Packer::getDefaultCompressionMethods_8(method, level);
|
||||
}
|
||||
|
||||
|
||||
const int *PackPs1::getFilters() const
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Linker* PackPs1::newLinker() const
|
||||
{
|
||||
class ElfLinkerMipsLE : public ElfLinker
|
||||
{
|
||||
typedef ElfLinker super;
|
||||
|
||||
virtual void relocate1(const Relocation *rel, upx_byte *location,
|
||||
unsigned value, const char *type)
|
||||
{
|
||||
if (strcmp(type, "R_MIPS_HI16") == 0)
|
||||
set_le16(location, get_le16(location) + MIPS_HI(value));
|
||||
else if (strcmp(type, "R_MIPS_LO16") == 0)
|
||||
set_le16(location, get_le16(location) + MIPS_LO(value));
|
||||
else if (strcmp(type, "R_MIPS_PC16") == 0)
|
||||
{
|
||||
value -= rel->section->offset + rel->offset;
|
||||
set_le16(location, get_le16(location) + MIPS_PC16(value));
|
||||
}
|
||||
else if (strcmp(type, "R_MIPS_26") == 0)
|
||||
set_le32(location, get_le32(location) + MIPS_PC26(value));
|
||||
else if (strcmp(type, "R_MIPS_32") == 0)
|
||||
set_le32(location, get_le32(location) + value);
|
||||
else
|
||||
super::relocate1(rel, location, value, type);
|
||||
}
|
||||
};
|
||||
return new ElfLinkerMipsLE;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
// util
|
||||
@@ -118,14 +148,86 @@ int PackPs1::readFileHeader()
|
||||
{
|
||||
fi->seek(0, SEEK_SET);
|
||||
fi->readx(&ih, sizeof(ih));
|
||||
if (memcmp(&ih.id,"PS-X EXE",8) != 0 &&
|
||||
memcmp(&ih.id,"EXE X-SP",8) != 0)
|
||||
if (memcmp(&ih.id, "PS-X EXE", 8) != 0 &&
|
||||
memcmp(&ih.id, "EXE X-SP", 8) != 0)
|
||||
return 0;
|
||||
if (ih.text != 0 || ih.data != 0)
|
||||
return 0;
|
||||
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;
|
||||
|
||||
if (src && dst)
|
||||
{
|
||||
unsigned char *cpr_bh = new unsigned char[MemBuffer::getSizeForCompression(SZ_IH_BKUP)];
|
||||
|
||||
memset(cpr_bh, 0, sizeof(bh));
|
||||
ps1_exe_chb_t * p = (ps1_exe_chb_t * )cpr_bh;
|
||||
|
||||
int r = upx_compress(src, SZ_IH_BKUP,
|
||||
&p->ih_bkup, &sz_cbh, NULL, M_NRV2E_8, 10, NULL, NULL );
|
||||
if (r != UPX_E_OK || sz_cbh >= SZ_IH_BKUP)
|
||||
throwInternalError("header compression failed");
|
||||
INIT_BH_BKUP(p, sz_cbh);
|
||||
*len = ALIGN_UP(sz_cbh + sizeof(ps1_exe_chb_t) - 1, 4);
|
||||
p->ih_csum = ADLER16(upx_adler32(&ih.epc, SZ_IH_BKUP));
|
||||
memcpy(dst, cpr_bh, SZ_IH_BKUP);
|
||||
delete [] cpr_bh;
|
||||
}
|
||||
else
|
||||
throwInternalError("header compression failed");
|
||||
}
|
||||
|
||||
#define ADLER16_HI(a, b) ((((a) & 0xffff) ^ (b)) << 16)
|
||||
#define ADLER16_LO(a, b) (((a) >> 16) ^ (b))
|
||||
#define RE_ADLER16(a, b) (ADLER16_HI(a,b) | ADLER16_LO(a,b))
|
||||
|
||||
bool PackPs1::getBkupHeader(unsigned char *p, unsigned char *dst)
|
||||
{
|
||||
ps1_exe_chb_t *src = (ps1_exe_chb_t*)p;
|
||||
|
||||
if (src && (src->id == '1' && src->len < SZ_IH_BKUP) && dst)
|
||||
{
|
||||
unsigned char *unc_bh = new unsigned char[MemBuffer::getSizeForUncompression(SZ_IH_BKUP)];
|
||||
|
||||
unsigned sz_bh = SZ_IH_BKUP;
|
||||
int r = upx_decompress((const unsigned char *)&src->ih_bkup, src->len,
|
||||
unc_bh, &sz_bh, M_NRV2E_8, NULL );
|
||||
if (r != UPX_E_OK || sz_bh != SZ_IH_BKUP)
|
||||
throwInternalError("header decompression failed");
|
||||
unsigned ad = upx_adler32(unc_bh, SZ_IH_BKUP);
|
||||
unsigned ch = src->ih_csum;
|
||||
if (ad != RE_ADLER16(ad,ch))
|
||||
throwInternalError("backup header damaged");
|
||||
memcpy(dst, unc_bh, SZ_IH_BKUP);
|
||||
delete [] unc_bh;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PackPs1::checkFileHeader()
|
||||
{
|
||||
@@ -148,57 +250,24 @@ bool PackPs1::checkFileHeader()
|
||||
infoWarning("unsupported header field entry");
|
||||
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");
|
||||
return false;
|
||||
if (!opt->force)
|
||||
return false;
|
||||
else
|
||||
infoWarning("%s: stack pointer offset low", fi->getName());
|
||||
}
|
||||
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()
|
||||
{
|
||||
unsigned char buf[PS_HDR_SIZE-HD_CODE_OFS];
|
||||
unsigned char buf[PS_HDR_SIZE - sizeof(ps1_exe_t)];
|
||||
|
||||
if (!readFileHeader())
|
||||
return false;
|
||||
@@ -221,7 +290,7 @@ bool PackPs1::canPack()
|
||||
throwCantPack("unsupported header flags (try --force)");
|
||||
if (!opt->force && file_size < PS_MIN_SIZE)
|
||||
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)");
|
||||
return true;
|
||||
}
|
||||
@@ -233,44 +302,184 @@ bool PackPs1::canPack()
|
||||
|
||||
int PackPs1::buildLoader(const Filter *)
|
||||
{
|
||||
if (isCon)
|
||||
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);
|
||||
const char *method = NULL;
|
||||
|
||||
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)
|
||||
addLoader("PS1N2D08", NULL);
|
||||
method = isCon ? "nrv2d.small,8bit.sub,nrv.done" :
|
||||
"nrv2d.8bit,nrv.done";
|
||||
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)
|
||||
addLoader("PS1N2B32", NULL);
|
||||
method = isCon ? "nrv2b.small,32bit.sub,nrv.done" :
|
||||
"nrv2b.32bit,nrv.done";
|
||||
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)
|
||||
addLoader("PS1N2E32", NULL);
|
||||
method = isCon ? "nrv2e.small,32bit.sub,nrv.done" :
|
||||
"nrv2e.32bit,nrv.done";
|
||||
else if (ph.method == M_LZMA)
|
||||
method = "nrv2b.small,8bit.sub,nrv.done,lzma.prep";
|
||||
else
|
||||
throwInternalError("unknown compression method");
|
||||
|
||||
if (sa_cnt)
|
||||
addLoader(sa_cnt > (0x10000 << 2) ? "PS1MSETB" : "PS1MSETS",
|
||||
ih.tx_len & 3 ? "PS1MSETU" : "PS1MSETA",
|
||||
NULL);
|
||||
unsigned sa_tmp = sa_cnt;
|
||||
if (ph.overlap_overhead > sa_cnt)
|
||||
{
|
||||
if (!opt->force)
|
||||
{
|
||||
infoWarning("not in-place decompressible");
|
||||
throwCantPack("packed data overlap (try --force)");
|
||||
}
|
||||
else
|
||||
sa_tmp += overlap = ALIGN_UP((ph.overlap_overhead - sa_tmp),4);
|
||||
}
|
||||
|
||||
addLoader("PS1EXITC", "IDENTSTR", "PS1PAHDR",
|
||||
isCon ? "PS1SREGS" : "",
|
||||
NULL);
|
||||
foundBss = findBssSection();
|
||||
|
||||
if (ph.method == M_LZMA && !buildPart2)
|
||||
{
|
||||
initLoader(nrv_loader, sizeof(nrv_loader));
|
||||
addLoader("decompressor.start",
|
||||
isCon ? "LZMA_DEC20" : "LZMA_DEC10", "lzma.init", NULL);
|
||||
addLoader(sa_tmp > (0x10000 << 2) ? "memset.long" : "memset.short",
|
||||
!foundBss ? "con.exit" : "bss.exit", NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ph.method == M_LZMA && buildPart2)
|
||||
{
|
||||
sz_lcpr = MemBuffer::getSizeForCompression(sz_lunc);
|
||||
unsigned char *cprLoader = new unsigned char[sz_lcpr];
|
||||
int r = upx_compress(getLoader(), sz_lunc, cprLoader, &sz_lcpr,
|
||||
NULL, M_NRV2B_8, 10, NULL, NULL );
|
||||
if (r != UPX_E_OK || sz_lcpr >= sz_lunc)
|
||||
throwInternalError("loader compression failed");
|
||||
initLoader(nrv_loader, sizeof(nrv_loader),
|
||||
(ph.method != M_LZMA || isCon) ? 0 : 1);
|
||||
linker->addSection("lzma.exec", cprLoader, sz_lcpr, 0);
|
||||
delete [] cprLoader;
|
||||
}
|
||||
else
|
||||
initLoader(nrv_loader, sizeof(nrv_loader));
|
||||
|
||||
pad_code = ALIGN_GAP((ph.c_len + (isCon ? sz_lcpr : 0)), 4);
|
||||
linker->addSection("pad.code", &pad_code, pad_code, 0);
|
||||
|
||||
if (isCon)
|
||||
{
|
||||
if (ph.method == M_LZMA)
|
||||
addLoader(!foundBss ? "con.start" : "bss.con.start",
|
||||
method,
|
||||
ih.tx_ptr & 0xffff ? "dec.ptr" : "dec.ptr.hi",
|
||||
"con.entry", "pad.code", "lzma.exec", NULL);
|
||||
else
|
||||
addLoader(!foundBss ? "con.start" : "bss.con.start", "con.mcpy",
|
||||
ph.c_len & 3 ? "con.padcd" : "",
|
||||
ih.tx_ptr & 0xffff ? "dec.ptr" : "dec.ptr.hi",
|
||||
"con.entry", method,
|
||||
sa_cnt ? sa_cnt > (0x10000 << 2) ? "memset.long" : "memset.short" : "",
|
||||
!foundBss ? "con.exit" : "bss.exit",
|
||||
"pad.code", NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ph.method == M_LZMA)
|
||||
addLoader("cdb.start.lzma", "pad.code", "cdb.entry.lzma", method, "cdb.lzma.cpr",
|
||||
ih.tx_ptr & 0xffff ? "dec.ptr" : "dec.ptr.hi",
|
||||
"lzma.exec", NULL);
|
||||
else
|
||||
addLoader("cdb.start", "pad.code", "cdb.entry",
|
||||
ih.tx_ptr & 0xffff ? "cdb.dec.ptr" : "cdb.dec.ptr.hi",
|
||||
method,
|
||||
sa_cnt ? sa_cnt > (0x10000 << 2) ? "memset.long" : "memset.short" : "",
|
||||
!foundBss ? "cdb.exit" : "bss.exit",
|
||||
"pad.code", NULL);
|
||||
}
|
||||
addLoader("UPX1HEAD", "IDENTSTR", NULL);
|
||||
}
|
||||
freezeLoader();
|
||||
return getLoaderSize();
|
||||
}
|
||||
|
||||
#define OPTYPE(x) (((x) >> 13) & 0x7)
|
||||
#define OPCODE(x) (((x) >> 10) & 0x7)
|
||||
#define REG1(x) (((x) >> 5) & 0x1f)
|
||||
#define REG2(x) ((x) & 0x1f)
|
||||
|
||||
#define MIPS_IMM(a,b) (((a) - (((b) & 0x8000) >> 15) << 16) | (b))
|
||||
|
||||
// Type
|
||||
#define REGIMM 1
|
||||
#define STORE 5
|
||||
// Op
|
||||
#define LUI 7
|
||||
#define ADDIU 1
|
||||
#define SW 3
|
||||
|
||||
#define IS_LUI(a) ((OPTYPE(a) == REGIMM && OPCODE(a) == LUI))
|
||||
#define IS_ADDIU(a) ((OPTYPE(a) == REGIMM && OPCODE(a) == ADDIU))
|
||||
#define IS_SW_ZERO(a) ((OPTYPE(a) == STORE && OPCODE(a) == SW) && REG2(a) == 0)
|
||||
|
||||
#define BSS_CHK_LIMIT (18)
|
||||
|
||||
bool PackPs1::findBssSection()
|
||||
{
|
||||
unsigned char reg;
|
||||
LE32 *p1 = (LE32 *)(ibuf + (ih.epc - ih.tx_ptr));
|
||||
|
||||
if ((ih.epc - ih.tx_ptr + (BSS_CHK_LIMIT * 4)) > fdata_size)
|
||||
return false;
|
||||
|
||||
// check 18 opcodes for sw zero,0(x)
|
||||
for (signed i = BSS_CHK_LIMIT; i >= 0; i--)
|
||||
{
|
||||
unsigned short op = p1[i] >> 16;
|
||||
if (IS_SW_ZERO(op))
|
||||
{
|
||||
// found! get reg (x) for bss_start
|
||||
reg = REG1(op);
|
||||
for (; i >= 0; i--)
|
||||
{
|
||||
bss_nfo *p = (bss_nfo *)&p1[i];
|
||||
unsigned short op1 = p->op1, op2 = p->op2;
|
||||
|
||||
// check for la (x),bss_start
|
||||
if ((IS_LUI(op1) && REG2(op1) == reg) &&
|
||||
(IS_ADDIU(op2) && REG1(op2) == reg))
|
||||
{
|
||||
op1 = p->op3, op2 = p->op4;
|
||||
|
||||
// check for la (y),bss_end
|
||||
if (IS_LUI(op1) && IS_ADDIU(op2))
|
||||
{
|
||||
// bss section info found!
|
||||
bss_start = MIPS_IMM(p->hi1, p->lo1);
|
||||
bss_end = MIPS_IMM(p->hi2, p->lo2);
|
||||
|
||||
if (0 < ALIGN_DOWN(bss_end - bss_start, 4) )
|
||||
{
|
||||
unsigned wkmem_sz = (ph.method == M_LZMA) ? 32768 : 800;
|
||||
unsigned end_offs = ih.tx_ptr + fdata_size + overlap;
|
||||
if (bss_end > (end_offs + wkmem_sz))
|
||||
return (isCon || (!isCon && (ph.method == M_LZMA)));
|
||||
else
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
@@ -280,7 +489,7 @@ void PackPs1::pack(OutputFile *fo)
|
||||
{
|
||||
ibuf.alloc(fdata_size);
|
||||
obuf.allocForCompression(fdata_size);
|
||||
const upx_byte *p_scan = ibuf+fdata_size;
|
||||
const upx_byte *p_scan = ibuf + fdata_size;
|
||||
|
||||
// read file
|
||||
fi->seek(PS_HDR_SIZE,SEEK_SET);
|
||||
@@ -288,9 +497,9 @@ void PackPs1::pack(OutputFile *fo)
|
||||
|
||||
// scan EOF for 2048 bytes sector alignment
|
||||
// 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);
|
||||
else
|
||||
sa_cnt = ALIGN_DOWN(sa_cnt,4);
|
||||
@@ -301,29 +510,47 @@ void PackPs1::pack(OutputFile *fo)
|
||||
Filter ft(ph.level);
|
||||
|
||||
// compress (max_match = 65535)
|
||||
compressWithFilters(&ft, 512, 0, NULL, 0, 65535);
|
||||
upx_compress_config_t cconf; cconf.reset();
|
||||
cconf.conf_ucl.max_match = 65535;
|
||||
cconf.conf_lzma.max_num_probs = 1846 + (768 << 4); // ushort: ~28KB stack
|
||||
compressWithFilters(&ft, sa_cnt, 0, NULL, &cconf);
|
||||
|
||||
if (ph.overlap_overhead > sa_cnt)
|
||||
if (overlap)
|
||||
{
|
||||
if (!opt->force)
|
||||
{
|
||||
infoWarning("not in-place decompressible");
|
||||
throwCantPack("packed data overlap (try --force)");
|
||||
}
|
||||
else
|
||||
{
|
||||
overlap = ALIGN_UP((ph.overlap_overhead-sa_cnt),4);
|
||||
opt->info_mode += !opt->info_mode ? 1 : 0;
|
||||
infoWarning("%s: memory overlap %d bytes",fi->getName(),overlap);
|
||||
}
|
||||
opt->info_mode += !opt->info_mode ? 1 : 0;
|
||||
infoWarning("overlap - relocating load address (+%d bytes)", overlap);
|
||||
sa_cnt += overlap;
|
||||
}
|
||||
|
||||
/*
|
||||
if (bss_start && bss_end && !foundBss)
|
||||
infoWarning("%s: .bss section too small - use stack", fi->getName());
|
||||
*/
|
||||
|
||||
unsigned lzma_init = 0;
|
||||
|
||||
if (ph.method == M_LZMA)
|
||||
{
|
||||
sz_lunc = getLoaderSize();
|
||||
|
||||
lzma_init = 0u - (sz_lunc - linker->getSymbolOffset("lzma.init"));
|
||||
defineDecompressorSymbols();
|
||||
linker->defineSymbol("entry", ih.epc);
|
||||
linker->defineSymbol("SC",
|
||||
sa_cnt > (0x10000 << 2) ? sa_cnt >> 5 : sa_cnt >> 2);
|
||||
linker->relocate();
|
||||
|
||||
buildPart2 = true;
|
||||
buildLoader(&ft);
|
||||
}
|
||||
|
||||
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)
|
||||
oh.is_ptr = PS_RAM_SIZE-0x10;
|
||||
unsigned sz_cbh;
|
||||
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 ||
|
||||
ih.bs_ptr != 0 || ih.bs_len != 0)
|
||||
@@ -334,44 +561,45 @@ void PackPs1::pack(OutputFile *fo)
|
||||
MemBuffer loader(lsize);
|
||||
memcpy(loader, getLoader(), lsize);
|
||||
|
||||
patchPackHeader(loader,lsize);
|
||||
|
||||
unsigned pad = 0;
|
||||
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 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 c_len = lsize - h_len;
|
||||
const int h_len = lsize - getLoaderSectionStart("UPX1HEAD");
|
||||
int d_len = 0;
|
||||
int e_len = 0;
|
||||
|
||||
if (isCon)
|
||||
{
|
||||
e_len = lsize - h_len;
|
||||
d_len = e_len - getLoaderSectionStart("PS1ENTRY");
|
||||
d_len = e_len - getLoaderSectionStart("con.entry");
|
||||
}
|
||||
else
|
||||
{
|
||||
d_len = (lsize - h_len) - getLoaderSectionStart("PS1ENTRY");
|
||||
d_len = (lsize - h_len) - getLoaderSectionStart((ph.method == M_LZMA) ? "cdb.entry.lzma" : "cdb.entry");
|
||||
e_len = (lsize - d_len) - h_len;
|
||||
}
|
||||
|
||||
patch_mips_le(loader,c_len,"JPEP",MIPS_JP(ih.epc));
|
||||
if (sa_cnt)
|
||||
patch_mips_le(loader,c_len,"SC",
|
||||
MIPS_LO(sa_cnt > (0x10000 << 2) ? sa_cnt >> 5 : sa_cnt >> 2));
|
||||
if (ih.tx_ptr & 0xffff)
|
||||
patch_mips_le(loader,c_len,"DECO",decomp_data_start);
|
||||
else
|
||||
patch_mips_le(loader,c_len,"DE",MIPS_HI(decomp_data_start));
|
||||
linker->defineSymbol("entry", ih.epc);
|
||||
linker->defineSymbol("SC", MIPS_LO(sa_cnt > (0x10000 << 2) ?
|
||||
sa_cnt >> 5 : sa_cnt >> 2));
|
||||
linker->defineSymbol("DECO", decomp_data_start);
|
||||
linker->defineSymbol("ldr_sz", (ph.method == M_LZMA ? sz_lunc + 16 : (d_len-pad_code)));
|
||||
|
||||
const unsigned entry = comp_data_start - e_len - pad_code;
|
||||
oh.tx_ptr = entry;
|
||||
oh.tx_len = ph.c_len + e_len + pad_code;
|
||||
oh.epc = comp_data_start - e_len - pad_code;
|
||||
if (foundBss)
|
||||
if (ph.method == M_LZMA)
|
||||
linker->defineSymbol("wrkmem", bss_end - 160 - getDecompressorWrkmemSize()
|
||||
- (sz_lunc + 16));
|
||||
else
|
||||
linker->defineSymbol("wrkmem", bss_end - 16 - (d_len - pad_code));
|
||||
|
||||
|
||||
const unsigned entry = comp_data_start - e_len;
|
||||
oh.epc = oh.tx_ptr = entry;
|
||||
oh.tx_len = ph.c_len + e_len;
|
||||
|
||||
unsigned pad = 0;
|
||||
|
||||
if (!opt->ps1_exe.no_align)
|
||||
{
|
||||
@@ -384,43 +612,50 @@ void PackPs1::pack(OutputFile *fo)
|
||||
ibuf.clear(0,fdata_size);
|
||||
upx_bytep paddata = ibuf;
|
||||
|
||||
if (ph.method == M_LZMA)
|
||||
{
|
||||
linker->defineSymbol("lzma_init_off", lzma_init);
|
||||
linker->defineSymbol("gb_e", linker->getSymbolOffset("gb8_e"));
|
||||
}
|
||||
else
|
||||
if (isCon)
|
||||
linker->defineSymbol("gb_e", linker->getSymbolOffset(is32Bit ? "gb32_e" : "gb8_e"));
|
||||
|
||||
if (isCon)
|
||||
{
|
||||
if (pad_code)
|
||||
patch_mips_le(loader, c_len, "PC", pad_code);
|
||||
patch_mips_le(loader, c_len, "DCRT", entry + (e_len - d_len));
|
||||
patch_mips_le(loader, c_len, "LS",
|
||||
d_len + get_le32(&loader[getLoaderSectionStart("PS1SREGS")]));
|
||||
|
||||
// ps1_exe_t structure 188 bytes
|
||||
fo->write(&oh,sizeof(oh));
|
||||
// id & upx header
|
||||
fo->write(loader + e_len,h_len);
|
||||
linker->defineSymbol("PAD", pad_code);
|
||||
if (ph.method == M_LZMA)
|
||||
linker->defineSymbol("DCRT", (entry + getLoaderSectionStart("lzma.exec")));
|
||||
else
|
||||
linker->defineSymbol("DCRT", (entry + (e_len - d_len)));
|
||||
}
|
||||
else
|
||||
{
|
||||
patch_mips_le(loader, c_len, "CPDO", comp_data_start);
|
||||
patch_mips_le(loader, e_len, "PSVR", FIX_PSVR);
|
||||
|
||||
// ps1_exe_t structure 188 bytes
|
||||
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);
|
||||
linker->defineSymbol("PSVR", FIX_PSVR);
|
||||
linker->defineSymbol("CPDO", comp_data_start);
|
||||
if (ph.method == M_LZMA)
|
||||
linker->defineSymbol("lzma_cpr", getLoaderSectionStart("lzma.exec")
|
||||
- getLoaderSectionStart("cdb.entry.lzma"));
|
||||
}
|
||||
|
||||
// header size is 2048 bytes
|
||||
fo->write(paddata, PS_HDR_SIZE - fo->getBytesWritten());
|
||||
// sector alignment
|
||||
if (pad)
|
||||
fo->write(paddata, pad);
|
||||
linker->relocate();
|
||||
memcpy(loader, getLoader(), lsize);
|
||||
patchPackHeader(loader, lsize);
|
||||
|
||||
if (!isCon && ph.method == M_LZMA && (HD_CODE_OFS + d_len + h_len) > CD_SEC)
|
||||
throwInternalError("lzma --boot-only loader > 2048");
|
||||
|
||||
// ps1_exe_t structure
|
||||
fo->write(&oh, sizeof(oh));
|
||||
fo->write(&bh, sz_cbh);
|
||||
// decompressor
|
||||
fo->write(loader + e_len, isCon ? h_len : (d_len + h_len));
|
||||
|
||||
// header size is 2048 bytes + sector alignment
|
||||
fo->write(paddata, (pad + PS_HDR_SIZE) - fo->getBytesWritten());
|
||||
// entry
|
||||
fo->write(loader, e_len);
|
||||
// code must be aligned to 4!
|
||||
if (pad_code)
|
||||
fo->write(paddata, pad_code);
|
||||
// compressed binary / data
|
||||
// compressed body
|
||||
fo->write(obuf, ph.c_len);
|
||||
|
||||
verifyOverlappingDecompression();
|
||||
@@ -428,15 +663,23 @@ void PackPs1::pack(OutputFile *fo)
|
||||
throwNotCompressible();
|
||||
|
||||
#if 0
|
||||
printf("%-13s: uncompressed : %8ld bytes\n", getName(), (long) ph.u_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: code entry : %08X bytes\n", getName(), (unsigned int) oh.epc);
|
||||
printf("%-13s: load address : %08X bytes\n", getName(), (unsigned int) oh.tx_ptr);
|
||||
printf("%-13s: eof in mem IF: %08X bytes\n", getName(), (unsigned int) ih.tx_ptr+ih.tx_len);
|
||||
printf("%-13s: eof in mem OF: %08X bytes\n", getName(), (unsigned int) oh.tx_ptr+oh.tx_len);
|
||||
printf("%-13s: uncompressed : %8ld bytes\n", getName(), (long) ph.u_len);
|
||||
printf("%-13s: compressed : %8ld bytes\n", getName(), (long) ph.c_len);
|
||||
printf("%-13s: decompressor : %8ld bytes\n", getName(), (long) lsize - h_len - pad_code);
|
||||
printf("%-13s: header comp : %8ld bytes\n", getName(), (long) sz_cbh);
|
||||
printf("%-13s: overlap : %8ld bytes\n", getName(), (long) overlap);
|
||||
printf("%-13s: load address : %08X bytes\n", getName(), (unsigned int) oh.tx_ptr);
|
||||
printf("%-13s: 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 (ph.method == M_LZMA) { if (!foundBss) i = 3; else i = 4; } }
|
||||
const char *loader_method[] = { "con/stack", "con/bss", "cdb", "cdb/stack", "cdb/bss" };
|
||||
char method_name[32+1]; set_method_name(method_name, sizeof(method_name), ph.method, ph.level);
|
||||
printf("%-13s: compressor : %s\n", getName(), method_name);
|
||||
printf("%-13s: methods : %s, %s\n", getName(), method_name, loader_method[i]);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -449,11 +692,10 @@ int PackPs1::canUnpack()
|
||||
{
|
||||
if (!readFileHeader())
|
||||
return false;
|
||||
if (!readPackHeader(1024))
|
||||
if (!readPackHeader(CD_SEC))
|
||||
return false;
|
||||
// check header as set by packer
|
||||
if (ih.ih_csum != upx_adler32(&ih.ih_bkup, SZ_IH_BKUP) &&
|
||||
(ph.c_len >= fdata_size))
|
||||
if (!readBkupHeader() || ph.c_len >= fdata_size)
|
||||
throwCantUnpack("header damaged");
|
||||
// generic check
|
||||
if (!checkFileHeader())
|
||||
@@ -470,7 +712,7 @@ void PackPs1::unpack(OutputFile *fo)
|
||||
{
|
||||
// restore orig exec hdr
|
||||
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
|
||||
assert(oh.tx_len >= ph.u_len);
|
||||
@@ -482,9 +724,6 @@ void PackPs1::unpack(OutputFile *fo)
|
||||
fi->seek(PS_HDR_SIZE, SEEK_SET);
|
||||
fi->readx(ibuf, fdata_size);
|
||||
|
||||
// clear backup and checksum of header
|
||||
memset(&oh.ih_bkup, 0, SZ_IH_BKUP+4);
|
||||
|
||||
// decompress
|
||||
decompress(ibuf + (fdata_size - ph.c_len), obuf);
|
||||
|
||||
@@ -495,14 +734,14 @@ void PackPs1::unpack(OutputFile *fo)
|
||||
fo->write(&oh, sizeof(oh));
|
||||
// align the ps exe header (mode 2 sector data size)
|
||||
ibuf.clear();
|
||||
fo->write(ibuf, PS_HDR_SIZE - fo->getBytesWritten());
|
||||
// write uncompressed data + pad
|
||||
fo->write(ibuf, PS_HDR_SIZE - sizeof(oh));
|
||||
obuf.clear(ph.u_len, pad);
|
||||
fo->write(obuf, ph.u_len + pad);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
vi:ts=4:et:nowrap
|
||||
*/
|
||||
|
||||
|
||||
+39
-13
@@ -2,9 +2,9 @@
|
||||
|
||||
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) 2002-2004 Jens Medoch
|
||||
Copyright (C) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
Copyright (C) 2002-2006 Jens Medoch
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -56,8 +56,12 @@ public:
|
||||
virtual int canUnpack();
|
||||
|
||||
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 bool getBkupHeader(unsigned char *src, unsigned char * dst);
|
||||
virtual bool readBkupHeader();
|
||||
virtual int buildLoader(const Filter *ft);
|
||||
virtual bool findBssSection();
|
||||
virtual Linker* newLinker() const;
|
||||
|
||||
virtual int readFileHeader();
|
||||
virtual bool checkFileHeader();
|
||||
@@ -84,24 +88,48 @@ protected:
|
||||
LE32 sp, fp, gp0, ra, k0;
|
||||
// origin Jap/USA/Europe
|
||||
char origin[60];
|
||||
|
||||
// some safety space after that
|
||||
char pad[8];
|
||||
// backup of the original header (epc - is_len)
|
||||
// id & the upx header ...
|
||||
}
|
||||
__attribute_packed;
|
||||
|
||||
// for unpack
|
||||
struct ps1_exe_hb_t
|
||||
{
|
||||
LE32 ih_bkup[10];
|
||||
// plus checksum for the backup
|
||||
LE32 ih_csum;
|
||||
// id & the upx header.
|
||||
}
|
||||
__attribute_packed;
|
||||
|
||||
struct ps1_exe_chb_t
|
||||
{
|
||||
unsigned char id;
|
||||
unsigned char len;
|
||||
LE16 ih_csum;
|
||||
unsigned char ih_bkup;
|
||||
}
|
||||
__attribute_packed;
|
||||
|
||||
typedef struct bss_nfo
|
||||
{
|
||||
LE16 hi1, op1, lo1, op2;
|
||||
LE16 hi2, op3, lo2, op4;
|
||||
}
|
||||
__attribute_packed;
|
||||
|
||||
ps1_exe_t ih, oh;
|
||||
ps1_exe_hb_t bh;
|
||||
|
||||
bool isCon;
|
||||
bool is32Bit;
|
||||
unsigned overlap;
|
||||
unsigned sa_cnt;
|
||||
|
||||
bool buildPart2;
|
||||
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
|
||||
unsigned fdata_size;
|
||||
};
|
||||
@@ -113,5 +141,3 @@ protected:
|
||||
/*
|
||||
vi:ts=4:et
|
||||
*/
|
||||
|
||||
|
||||
|
||||
+21
-23
@@ -2,8 +2,8 @@
|
||||
|
||||
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) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -22,7 +22,7 @@
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
markus@oberhumer.com ml1050@cdata.tvnet.hu
|
||||
markus@oberhumer.com ml1050@users.sourceforge.net
|
||||
*/
|
||||
|
||||
|
||||
@@ -32,9 +32,10 @@
|
||||
#include "packer.h"
|
||||
#include "p_com.h"
|
||||
#include "p_sys.h"
|
||||
#include "linker.h"
|
||||
|
||||
static const
|
||||
#include "stub/l_sys.h"
|
||||
#include "stub/i086-dos16.sys.h"
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
@@ -67,7 +68,6 @@ void PackSys::patchLoader(OutputFile *fo,
|
||||
upx_byte *loader, int lsize,
|
||||
unsigned calls)
|
||||
{
|
||||
const int filter_id = ph.filter;
|
||||
const int e_len = getLoaderSectionStart("SYSCUTPO");
|
||||
const int d_len = lsize - e_len;
|
||||
assert(e_len > 0 && e_len < 256);
|
||||
@@ -76,25 +76,22 @@ void PackSys::patchLoader(OutputFile *fo,
|
||||
if (ph.u_len + d_len + ph.overlap_overhead > 0xfffe)
|
||||
throwNotCompressible();
|
||||
|
||||
memcpy(loader,ibuf,6); // copy from orig. header
|
||||
memcpy(loader+8,ibuf+8,2); // opendos wants this word too
|
||||
// use some fields of the original file
|
||||
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;
|
||||
|
||||
patch_le16(loader,lsize,"JO",get_le16(ibuf+6)-copy_to-1);
|
||||
if (filter_id)
|
||||
{
|
||||
assert(calls > 0);
|
||||
patch_le16(loader,lsize,"CT",calls);
|
||||
}
|
||||
linker->defineSymbol("calltrick_calls", calls);
|
||||
linker->defineSymbol("copy_source", ph.c_len + lsize - 1);
|
||||
linker->defineSymbol("copy_destination", copy_to);
|
||||
linker->defineSymbol("NRV2B160", ph.u_len + ph.overlap_overhead + 1);
|
||||
linker->defineSymbol("original_strategy", get_le16(ibuf + 6));
|
||||
|
||||
linker->relocate();
|
||||
loader = getLoader();
|
||||
|
||||
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
|
||||
fo->write(loader,e_len); // entry
|
||||
fo->write(obuf,ph.c_len);
|
||||
@@ -107,12 +104,12 @@ int PackSys::buildLoader(const Filter *ft)
|
||||
initLoader(nrv2b_loader,sizeof(nrv2b_loader));
|
||||
addLoader("SYSMAIN1",
|
||||
opt->cpu == opt->CPU_8086 ? "SYSI0861" : "SYSI2861",
|
||||
"SYSMAIN2""SYSSUBSI",
|
||||
"SYSMAIN2",
|
||||
ph.first_offset_found == 1 ? "SYSSBBBP" : "",
|
||||
ft->id ? "SYSCALLT" : "",
|
||||
"SYSMAIN3""UPX1HEAD""SYSCUTPO""NRV2B160""NRVDDONE""NRVDECO1",
|
||||
"SYSMAIN3,UPX1HEAD,SYSCUTPO,NRV2B160,NRVDDONE,NRVDECO1",
|
||||
ph.max_offset_found <= 0xd00 ? "NRVLED00" : "NRVGTD00",
|
||||
"NRVDECO2""NRV2B169",
|
||||
"NRVDECO2",
|
||||
NULL
|
||||
);
|
||||
if (ft->id)
|
||||
@@ -125,6 +122,7 @@ int PackSys::buildLoader(const Filter *ft)
|
||||
"SYSJUMP1",
|
||||
NULL
|
||||
);
|
||||
freezeLoader();
|
||||
return getLoaderSize();
|
||||
}
|
||||
|
||||
|
||||
+3
-3
@@ -2,8 +2,8 @@
|
||||
|
||||
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) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -22,7 +22,7 @@
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
markus@oberhumer.com ml1050@cdata.tvnet.hu
|
||||
markus@oberhumer.com ml1050@users.sourceforge.net
|
||||
*/
|
||||
|
||||
|
||||
|
||||
+50
-26
@@ -2,8 +2,8 @@
|
||||
|
||||
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) 1996-2006 Markus Franz Xaver Johannes Oberhumer
|
||||
Copyright (C) 1996-2006 Laszlo Molnar
|
||||
All Rights Reserved.
|
||||
|
||||
UPX and the UCL library are free software; you can redistribute them
|
||||
@@ -22,7 +22,7 @@
|
||||
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
|
||||
Markus F.X.J. Oberhumer Laszlo Molnar
|
||||
markus@oberhumer.com ml1050@cdata.tvnet.hu
|
||||
markus@oberhumer.com ml1050@users.sourceforge.net
|
||||
*/
|
||||
|
||||
|
||||
@@ -31,9 +31,10 @@
|
||||
#include "filter.h"
|
||||
#include "packer.h"
|
||||
#include "p_tmt.h"
|
||||
#include "linker.h"
|
||||
|
||||
static const
|
||||
#include "stub/l_tmt.h"
|
||||
#include "stub/i386-dos32.tmt.h"
|
||||
|
||||
#define EXTRA_INFO 4 // original entry point
|
||||
|
||||
@@ -74,28 +75,37 @@ unsigned PackTmt::findOverlapOverhead(const upx_bytep buf,
|
||||
}
|
||||
|
||||
|
||||
Linker* PackTmt::newLinker() const
|
||||
{
|
||||
return new ElfLinkerX86;
|
||||
}
|
||||
|
||||
|
||||
int PackTmt::buildLoader(const Filter *ft)
|
||||
{
|
||||
// prepare loader
|
||||
initLoader(nrv_loader,sizeof(nrv_loader));
|
||||
addLoader("IDENTSTR""TMTMAIN1",
|
||||
addLoader("IDENTSTR,TMTMAIN1",
|
||||
ft->id ? "TMTCALT1" : "",
|
||||
"TMTMAIN2""UPX1HEAD""TMTCUTPO""+0XXXXXX",
|
||||
getDecompressor(),
|
||||
"TMTMAIN5",
|
||||
NULL
|
||||
);
|
||||
"TMTMAIN2,UPX1HEAD,TMTCUTPO",
|
||||
NULL);
|
||||
|
||||
// fake alignment for the start of the decompressor
|
||||
linker->defineSymbol("TMTCUTPO", 0x1000);
|
||||
|
||||
addLoader(getDecompressorSections(), "TMTMAIN5", NULL);
|
||||
if (ft->id)
|
||||
{
|
||||
assert(ft->calls > 0);
|
||||
addLoader("TMTCALT2",NULL);
|
||||
addFilter32(ft->id);
|
||||
}
|
||||
addLoader("TMTRELOC""RELOC320",
|
||||
addLoader("TMTRELOC,RELOC320",
|
||||
big_relocs ? "REL32BIG" : "",
|
||||
"RELOC32J""TMTJUMP1",
|
||||
"RELOC32J,TMTJUMP1",
|
||||
NULL
|
||||
);
|
||||
freezeLoader();
|
||||
return getLoaderSize();
|
||||
}
|
||||
|
||||
@@ -175,6 +185,19 @@ bool PackTmt::canPack()
|
||||
}
|
||||
|
||||
|
||||
static bool defineFilterSymbols(Linker *linker, const Filter *ft)
|
||||
{
|
||||
if (ft->id == 0)
|
||||
return false;
|
||||
assert(ft->calls > 0);
|
||||
|
||||
linker->defineSymbol("filter_cto", ft->cto);
|
||||
linker->defineSymbol("filter_length",
|
||||
(ft->id & 0xf) % 3 == 0 ? ft->calls :
|
||||
ft->lastcall - ft->calls * 4);
|
||||
return true;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
//
|
||||
**************************************************************************/
|
||||
@@ -230,30 +253,31 @@ void PackTmt::pack(OutputFile *fo)
|
||||
compressWithFilters(&ft, 512);
|
||||
|
||||
const unsigned lsize = getLoaderSize();
|
||||
MemBuffer loader(lsize);
|
||||
memcpy(loader,getLoader(),lsize);
|
||||
|
||||
const unsigned s_point = getLoaderSection("TMTMAIN1");
|
||||
int e_len = getLoaderSectionStart("TMTCUTPO");
|
||||
const unsigned d_len = lsize - e_len;
|
||||
assert(e_len > 0 && s_point > 0);
|
||||
|
||||
// patch loader
|
||||
patch_le32(loader,lsize,"JMPO",ih.entry-(ph.u_len+ph.overlap_overhead+d_len));
|
||||
patchFilter32(loader, lsize, &ft);
|
||||
patchPackHeader(loader,e_len);
|
||||
linker->defineSymbol("original_entry", ih.entry);
|
||||
defineFilterSymbols(linker, &ft);
|
||||
defineDecompressorSymbols();
|
||||
|
||||
const unsigned jmp_pos = find_le32(loader,e_len,get_le32("JMPD"));
|
||||
patch_le32(loader,e_len,"JMPD",ph.u_len+ph.overlap_overhead-jmp_pos-4);
|
||||
|
||||
patch_le32(loader,e_len,"ECX0",ph.c_len+d_len);
|
||||
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",
|
||||
linker->defineSymbol("bytes_to_copy", ph.c_len + d_len);
|
||||
linker->defineSymbol("copy_dest", ph.u_len + ph.overlap_overhead + d_len - 1);
|
||||
linker->defineSymbol("copy_source", ph.c_len + lsize - 1);
|
||||
//fprintf(stderr,"\nelen=%x dlen=%x copy_len=%x copy_to=%x oo=%x jmp_pos=%x ulen=%x c_len=%x \n\n",
|
||||
// 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);
|
||||
linker->relocate();
|
||||
|
||||
MemBuffer loader(lsize);
|
||||
memcpy(loader,getLoader(),lsize);
|
||||
patchPackHeader(loader,e_len);
|
||||
|
||||
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.relocsize = 4;
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user