wok-next rev 17591
syslinux/isohybrib.exe: add --md5, --undo
author | Pascal Bellard <pascal.bellard@slitaz.org> |
---|---|
date | Tue Feb 10 08:53:27 2015 +0100 (2015-02-10) |
parents | 93ebe04d2558 |
children | 24b07aa2fafd |
files | syslinux/stuff/iso2exe/init syslinux/stuff/iso2exe/iso2exe.c syslinux/stuff/iso2exe/iso2exe.sh |
line diff
1.1 --- a/syslinux/stuff/iso2exe/init Mon Feb 09 21:52:32 2015 +0000 1.2 +++ b/syslinux/stuff/iso2exe/init Tue Feb 10 08:53:27 2015 +0100 1.3 @@ -655,7 +655,7 @@ 1.4 { 1.5 dotwait "Checking iso image" 1.6 [ "$(ddq if=/dev/loop0 bs=2k skip=16 \ 1.7 - count=$(echo $(get 32848 /dev/loop0)) | md5sum)" == \ 1.8 + count=$(echo $(get 32848 /dev/loop0 4)) | md5sum)" == \ 1.9 "$(ddq if=/dev/loop0 bs=16 count=1 skip=2047 | od -N 16 -t x1 -An | \ 1.10 sed 's/ //g') -" ] && echo "OK" || echo "ERROR" 1.11 echo -en "\rChecking iso hybrid boot"
2.1 --- a/syslinux/stuff/iso2exe/iso2exe.c Mon Feb 09 21:52:32 2015 +0000 2.2 +++ b/syslinux/stuff/iso2exe/iso2exe.c Tue Feb 10 08:53:27 2015 +0100 2.3 @@ -9,9 +9,11 @@ 2.4 #ifdef WIN32 2.5 #include <windows.h> 2.6 #endif 2.7 +typedef unsigned char uint8_t; 2.8 +typedef unsigned long uint32_t; 2.9 #include "iso2exe.h" 2.10 2.11 -static int fd, forced, status = 1; 2.12 +static int fd, forced, uninstall, status = 1; 2.13 static char tazlitoinfo[0x8000U - BOOTISOSZ]; 2.14 #define buffer tazlitoinfo 2.15 #define BUFFERSZ 2048 2.16 @@ -27,6 +29,217 @@ 2.17 } 2.18 } 2.19 2.20 +static int domd5 = 0; 2.21 +#define ALIGN1 2.22 + 2.23 +typedef struct { 2.24 + uint32_t l; 2.25 + uint32_t h; 2.26 +} uint64_t; 2.27 +static uint8_t wbuffer[64]; /* always correctly aligned for uint64_t */ 2.28 +static uint64_t total64; /* must be directly before hash[] */ 2.29 +static uint32_t hash[8]; /* 4 elements for md5, 5 for sha1, 8 for sha256 */ 2.30 + 2.31 +//#define rotl32(x,n) (((x) << (n)) | ((x) >> (32 - (n)))) 2.32 +static uint32_t rotl32(uint32_t x, unsigned n) 2.33 +{ 2.34 + return (x << n) | (x >> (32 - n)); 2.35 +} 2.36 + 2.37 +static void md5_process_block64(void); 2.38 + 2.39 +/* Feed data through a temporary buffer. 2.40 + * The internal buffer remembers previous data until it has 64 2.41 + * bytes worth to pass on. 2.42 + */ 2.43 +static void common64_hash(const void *buffer, size_t len) 2.44 +{ 2.45 + unsigned bufpos = total64.l & 63; 2.46 + 2.47 + total64.l += len; if (total64.l < len) total64.h++; 2.48 + 2.49 + while (1) { 2.50 + unsigned remaining = 64 - bufpos; 2.51 + if (remaining > len) 2.52 + remaining = len; 2.53 + /* Copy data into aligned buffer */ 2.54 + memcpy(wbuffer + bufpos, buffer, remaining); 2.55 + len -= remaining; 2.56 + buffer = (const char *)buffer + remaining; 2.57 + bufpos += remaining; 2.58 + /* clever way to do "if (bufpos != 64) break; ... ; bufpos = 0;" */ 2.59 + bufpos -= 64; 2.60 + if (bufpos != 0) 2.61 + break; 2.62 + /* Buffer is filled up, process it */ 2.63 + md5_process_block64(); 2.64 + /*bufpos = 0; - already is */ 2.65 + } 2.66 +} 2.67 + 2.68 +/* Process the remaining bytes in the buffer */ 2.69 +static void common64_end(void) 2.70 +{ 2.71 + unsigned bufpos = total64.l & 63; 2.72 + /* Pad the buffer to the next 64-byte boundary with 0x80,0,0,0... */ 2.73 + wbuffer[bufpos++] = 0x80; 2.74 + 2.75 + /* This loop iterates either once or twice, no more, no less */ 2.76 + while (1) { 2.77 + unsigned remaining = 64 - bufpos; 2.78 + memset(wbuffer + bufpos, 0, remaining); 2.79 + /* Do we have enough space for the length count? */ 2.80 + if (remaining >= 8) { 2.81 + /* Store the 64-bit counter of bits in the buffer */ 2.82 + //uint64_t t = total64 << 3; 2.83 + uint32_t *t = (uint32_t *) (&wbuffer[64 - 8]); 2.84 + /* wbuffer is suitably aligned for this */ 2.85 + //*(uint64_t *) (&wbuffer[64 - 8]) = t; 2.86 + t[0] = total64.l << 3; 2.87 + t[1] = (total64.h << 3) | (total64.l >> 29); 2.88 + } 2.89 + md5_process_block64(); 2.90 + if (remaining >= 8) 2.91 + break; 2.92 + bufpos = 0; 2.93 + } 2.94 +} 2.95 + 2.96 +/* These are the four functions used in the four steps of the MD5 algorithm 2.97 + * and defined in the RFC 1321. The first function is a little bit optimized 2.98 + * (as found in Colin Plumbs public domain implementation). 2.99 + * #define FF(b, c, d) ((b & c) | (~b & d)) 2.100 + */ 2.101 +#undef FF 2.102 +#undef FG 2.103 +#undef FH 2.104 +#undef FI 2.105 +#define FF(b, c, d) (d ^ (b & (c ^ d))) 2.106 +#define FG(b, c, d) FF(d, b, c) 2.107 +#define FH(b, c, d) (b ^ c ^ d) 2.108 +#define FI(b, c, d) (c ^ (b | ~d)) 2.109 + 2.110 +/* Hash a single block, 64 bytes long and 4-byte aligned */ 2.111 +static void md5_process_block64(void) 2.112 +{ 2.113 + uint32_t *words = (void*) wbuffer; 2.114 + uint32_t A = hash[0]; 2.115 + uint32_t B = hash[1]; 2.116 + uint32_t C = hash[2]; 2.117 + uint32_t D = hash[3]; 2.118 + 2.119 + const uint32_t *pc; 2.120 + const char *pp; 2.121 + const char *ps; 2.122 + int i; 2.123 + uint32_t temp; 2.124 + 2.125 + 2.126 + pc = C_array; 2.127 + pp = P_array; 2.128 + ps = S_array - 4; 2.129 + 2.130 + for (i = 0; i < 64; i++) { 2.131 + if ((i & 0x0f) == 0) 2.132 + ps += 4; 2.133 + temp = A; 2.134 + switch (i >> 4) { 2.135 + case 0: 2.136 + temp += FF(B, C, D); 2.137 + break; 2.138 + case 1: 2.139 + temp += FG(B, C, D); 2.140 + break; 2.141 + case 2: 2.142 + temp += FH(B, C, D); 2.143 + break; 2.144 + case 3: 2.145 + temp += FI(B, C, D); 2.146 + } 2.147 + temp += words[(int) (*pp++)] + *pc++; 2.148 + temp = rotl32(temp, ps[i & 3]); 2.149 + temp += B; 2.150 + A = D; 2.151 + D = C; 2.152 + C = B; 2.153 + B = temp; 2.154 + } 2.155 + /* Add checksum to the starting values */ 2.156 + hash[0] += A; 2.157 + hash[1] += B; 2.158 + hash[2] += C; 2.159 + hash[3] += D; 2.160 + 2.161 +} 2.162 +#undef FF 2.163 +#undef FG 2.164 +#undef FH 2.165 +#undef FI 2.166 + 2.167 +/* Initialize structure containing state of computation. 2.168 + * (RFC 1321, 3.3: Step 3) 2.169 + */ 2.170 +static void md5_begin(void) 2.171 +{ 2.172 + hash[0] = 0x67452301; 2.173 + hash[1] = 0xefcdab89; 2.174 + hash[2] = 0x98badcfe; 2.175 + hash[3] = 0x10325476; 2.176 + total64.l = total64.h = 0; 2.177 +} 2.178 + 2.179 +/* Used also for sha1 and sha256 */ 2.180 +#define md5_hash common64_hash 2.181 + 2.182 +/* Process the remaining bytes in the buffer and put result from CTX 2.183 + * in first 16 bytes following RESBUF. The result is always in little 2.184 + * endian byte order, so that a byte-wise output yields to the wanted 2.185 + * ASCII representation of the message digest. 2.186 + */ 2.187 +#define md5_end common64_end 2.188 + 2.189 +static void md5sum(void) 2.190 +{ 2.191 + unsigned long sectors = 0; 2.192 + int count; 2.193 + 2.194 + lseek(fd, 32768UL, SEEK_SET); 2.195 + 2.196 + md5_begin(); 2.197 + while ((count = read(fd, buffer, BUFFERSZ)) > 0) { 2.198 + if (sectors == 0) 2.199 + sectors = LONG(buffer + 80); 2.200 + md5_hash(buffer, count); 2.201 + if (--sectors == 0) 2.202 + break; 2.203 + } 2.204 + 2.205 + if (count < 0) 2.206 + return; 2.207 + 2.208 + md5_end(); 2.209 + 2.210 + lseek(fd, 32752UL, SEEK_SET); 2.211 + write(fd, hash, 16); 2.212 + memcpy(bootiso + BOOTISOSZ - 16, hash, 16); 2.213 +} 2.214 + 2.215 +static unsigned chksum(unsigned start, unsigned stop) 2.216 +{ 2.217 + unsigned i, n = 0; 2.218 + 2.219 + lseek(fd, 0UL /* (unsigned long) (start / BUFFERSZ) */, SEEK_SET); 2.220 + while (1) { 2.221 + if (read(fd, buffer, BUFFERSZ) != BUFFERSZ) 2.222 + return 0; 2.223 + for (i = start % BUFFERSZ; i < BUFFERSZ; i += 2, start += 2) { 2.224 + if (start >= stop) 2.225 + return - n; 2.226 + n += WORD(buffer + i); 2.227 + } 2.228 + } 2.229 +} 2.230 + 2.231 static unsigned install(char *filename) 2.232 { 2.233 #define heads 64 2.234 @@ -50,6 +263,23 @@ 2.235 if (fd == -1) 2.236 return OPENERR; 2.237 2.238 + if (uninstall) { 2.239 + struct { char check[sizeof(tazlitoinfo) - BUFFERSZ - 1024]; }; 2.240 + readsector(0UL); 2.241 + n = BUFFERSZ; 2.242 + if (WORD(buffer) == 23117) { 2.243 + readsector((unsigned long) buffer[69]); 2.244 + n = 0; 2.245 + } 2.246 + lseek(fd, 0UL, SEEK_SET); 2.247 + for (i = 0; i < 32; i++, n = BUFFERSZ) { 2.248 + write(fd, buffer + n, 1024); 2.249 + } 2.250 + close(fd); 2.251 + status = 0; 2.252 + return UNINSTALLMSG; 2.253 + } 2.254 + 2.255 if (forced == 0) { 2.256 status = 2; 2.257 /* Install hybridiso boot sector */ 2.258 @@ -105,18 +335,22 @@ 2.259 write(fd, tazlitoinfo, sizeof(tazlitoinfo)); 2.260 write(fd, bootiso + n, BOOTISOSZ - n); /* COM + rootfs + EXE/DOS */ 2.261 2.262 - /* Compute the checksum */ 2.263 - lseek(fd, 0UL, SEEK_SET); 2.264 - for (i = 66, n = 0, j = 0; j < 16; j++, i = 0) { 2.265 - if (read(fd, buffer, BUFFERSZ) != BUFFERSZ) 2.266 - goto nochksum; 2.267 - for (; i < BUFFERSZ; i += 2) 2.268 - n += WORD(buffer + i); 2.269 + if (domd5) { 2.270 + puts(bootiso + MD5MSG); 2.271 + md5sum(); 2.272 } 2.273 - WORD(bootiso + 64) = -n; 2.274 - lseek(fd, 0UL, SEEK_SET); 2.275 - write(fd, bootiso, 512); 2.276 -nochksum: 2.277 + 2.278 + /* Compute the boot checksums */ 2.279 + if ((WORD(bootiso + 64) = chksum(66, 32768)) != 0) { 2.280 + if (domd5) { 2.281 + lseek(fd, 0UL, SEEK_SET); 2.282 + write(fd, bootiso, 512); 2.283 + n = WORD(bootiso + 2) - 512*(WORD(bootiso + 4) - 1); 2.284 + WORD(bootiso + 18) = chksum(0, n) - 1; 2.285 + } 2.286 + lseek(fd, 0UL, SEEK_SET); 2.287 + write(fd, bootiso, 512); 2.288 + } 2.289 close(fd); 2.290 status = 0; 2.291 return SUCCESSMSG; 2.292 @@ -124,7 +358,16 @@ 2.293 2.294 int main(int argc, char *argv[]) 2.295 { 2.296 - forced = (argc > 2); 2.297 + int i; 2.298 + for (i = 2; i < argc; i++) { 2.299 + char *s = argv[i]; 2.300 + while ((unsigned)(*s - '-') <= ('/' - '-')) s++; 2.301 + switch (*s | 0x20) { 2.302 + case 'f' : forced++; break; 2.303 + case 'm' : domd5++; break; 2.304 + case 'u' : uninstall++; break; 2.305 + } 2.306 + } 2.307 puts(bootiso + install(argv[1])); 2.308 if (status > 1) 2.309 puts(bootiso + FORCEMSG);
3.1 --- a/syslinux/stuff/iso2exe/iso2exe.sh Mon Feb 09 21:52:32 2015 +0000 3.2 +++ b/syslinux/stuff/iso2exe/iso2exe.sh Tue Feb 10 08:53:27 2015 +0100 3.3 @@ -140,8 +140,49 @@ 3.4 3.5 #ifdef WIN32 3.6 static char $name[] = { 3.7 +/* head */ 3.8 $(hexdump -v -n $HSZ -e '" " 16/1 "0x%02X, "' -e '" // %04.4_ax |" 16/1 "%_p" "| \n"' $DATA | sed 's/ 0x ,/ /g') 3.9 +/* tail */ 3.10 $(hexdump -v -s $OFS -e '" " 16/1 "0x%02X, "' -e '" // %04.4_ax |" 16/1 "%_p" "| \n"' $DATA | sed 's/ 0x ,/ /g') 3.11 + 3.12 +/* These strange constants are defined in RFC 1321 as 3.13 + T[i] = (int)(4294967296.0 * fabs(sin(i))), i=1..64 3.14 + */ 3.15 +/* static const uint32_t C_array[64] */ 3.16 +EOT 3.17 + while read a b c d; do 3.18 + for i in $a $b $c $d; do 3.19 + echo $i | sed 's/0x\(..\)\(..\)\(..\)\(..\),/0x\4, 0x\3, 0x\2, 0x\1, /' 3.20 + done 3.21 + done <<EOT 3.22 + 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, 3.23 + 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, 3.24 + 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, 3.25 + 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, 3.26 + 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, 3.27 + 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, 3.28 + 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, 3.29 + 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, 3.30 + 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, 3.31 + 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, 3.32 + 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, 3.33 + 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, 3.34 + 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, 3.35 + 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, 3.36 + 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, 3.37 + 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391, 3.38 +EOT 3.39 + cat <<EOT 3.40 +/* static const char P_array[64] */ 3.41 + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, /* 1 */ 3.42 + 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, /* 2 */ 3.43 + 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, /* 3 */ 3.44 + 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9, /* 4 */ 3.45 +/* static const char S_array[16] */ 3.46 + 7, 12, 17, 22, 3.47 + 5, 9, 14, 20, 3.48 + 4, 11, 16, 23, 3.49 + 6, 10, 15, 21, 3.50 EOT 3.51 3.52 for mode in data offset ; do 3.53 @@ -158,21 +199,27 @@ 3.54 #else 3.55 static char *$name; 3.56 #endif 3.57 + 3.58 +#define C_array (uint32_t *) ($name + $(($BOOTISOSZ))) 3.59 +#define P_array (char *) ($name + $(($BOOTISOSZ+(64*4)))) 3.60 +#define S_array (char *) ($name + $(($BOOTISOSZ+(64*4)+64))) 3.61 #define ELTORITOOFS 3 3.62 EOT 3.63 fi 3.64 - echo "#define $tag $(($BOOTISOSZ+$ofs))" 3.65 + echo "#define $tag $(($BOOTISOSZ+(64*4)+64+16+$ofs))" 3.66 ofs=$(($(echo -en "$str\0" | wc -c)+$ofs)) 3.67 fi 3.68 done <<EOT 3.69 READSECTORERR Read sector failure. 3.70 -USAGE Usage: isohybrid.exe file.iso [--forced] 3.71 +USAGE Usage: isohybrid.exe file.iso [--forced|--undo|--md5] 3.72 OPENERR Can't open r/w the iso file. 3.73 ELTORITOERR No EL TORITO SPECIFICATION signature. 3.74 CATALOGERR Invalid boot catalog. 3.75 HYBRIDERR No isolinux.bin hybrid signature. 3.76 SUCCESSMSG Now you can create a USB key with your .iso file.\\\\nSimply rename it to a .exe file and run it. 3.77 FORCEMSG You can add --forced to proceed anyway. 3.78 +MD5MSG Computing md5sum... 3.79 +UNINSTALLMSG Uninstall done. 3.80 EOT 3.81 done 3.82 rm -rf $DATA 3.83 @@ -242,7 +289,7 @@ 3.84 ddq bs=1 seek=$((0x7FDE)) count=15 conv=notrunc of=$1 3.85 if [ $(stat -c %s $1) -gt 34816 ]; then 3.86 echo "Adding ISO image md5 at 7FF0 (16 bytes) ..." 3.87 - echo -en "$(ddq if=$1 bs=2k skip=16 count=$(get 32848 $1) | \ 3.88 + echo -en "$(ddq if=$1 bs=2k skip=16 count=$(get 32848 $1 4) | \ 3.89 md5sum | cut -c-32 | sed 's/\(..\)/\\x\1/g')" | \ 3.90 ddq bs=16 seek=2047 conv=notrunc of=$1 3.91 fi