Scramble.c - Echelon - Binhack details 0x8c00e29c - offset 0x629c in IP.BIN - my_rand() 8c00e29c: 75 93 mov.w 0x8c00e38a,r3 ! 0x83d 8c00e29e: 12 4f sts.l macl,@-r15 8c00e2a0: 42 62 mov.l @r4,r2 ; load stored seed 8c00e2a2: 73 91 mov.w 0x8c00e38c,r1 ! 0x2439 8c00e2a4: 37 02 mul.l r3,r2 ; multiply by 2109 (0x83d) 8c00e2a6: 72 92 mov.w 0x8c00e38e,r2 ! 0x7fff 8c00e2a8: 1a 03 sts macl,r3 8c00e2aa: 1c 33 add r1,r3 ; add 9273 (0x2439) to the product 8c00e2ac: 29 23 and r2,r3 ; mask out 15 lowest bits 8c00e2ae: 33 60 mov r3,r0 8c00e2b0: 32 24 mov.l r3,@r4 ; update seed 8c00e2b2: 37 d3 mov.l 0x8c00e390,r3 ! 0xc000 8c00e2b4: 3c 30 add r3,r0 ; add 0xc000 8c00e2b6: 0d 60 extu.w r0,r0 ; return lowest 16 bits 8c00e2b8: 0b 00 rts 8c00e2ba: 16 4f lds.l @r15+,macl 0x8c00e2bc - offset 0x62bc in IP.BIN - save() 8c00e2bc: 35 d1 mov.l 0x8c00e394,r1 ! 0xace00000 ; temp area 8c00e2be: 00 e6 mov #0,r6 8c00e2c0: 08 e7 mov #8,r7 ; loop 8 times (8 words = 32 bytes) 8c00e2c2: 63 63 mov r6,r3 8c00e2c4: 52 60 mov.l @r5,r0 ; get "file pointer" 8c00e2c6: 08 43 shll2 r3 8c00e2c8: 4c 33 add r4,r3 8c00e2ca: 6c 30 add r6,r0 8c00e2cc: 32 62 mov.l @r3,r2 ; read word from source 8c00e2ce: 01 76 add #1,r6 8c00e2d0: 72 36 cmp/hs r7,r6 8c00e2d2: 08 40 shll2 r0 8c00e2d4: f5 8f bf.s 0x8c00e2c2 8c00e2d6: 26 01 mov.l r2,@(r0,r1) ; and write to dst 8c00e2d8: 52 62 mov.l @r5,r2 8c00e2da: 08 72 add #8,r2 ; increment "file pointer" by 8 8c00e2dc: 0b 00 rts 8c00e2de: 22 25 mov.l r2,@r5 0x8c00e2e0 - offset 0x62e0 in IP.BIN - save_chunk() 8c00e2e0: e6 2f mov.l r14,@-r15 8c00e2e2: d6 2f mov.l r13,@-r15 8c00e2e4: c6 2f mov.l r12,@-r15 8c00e2e6: 22 4f sts.l pr,@-r15 8c00e2e8: 12 4f sts.l macl,@-r15 8c00e2ea: f4 7f add #-12,r15 8c00e2ec: 09 45 shlr2 r5 ; arg2 is divided by 32 8c00e2ee: 41 1f mov.l r4,@(4,r15) 8c00e2f0: 09 45 shlr2 r5 ; to get number of slices 8c00e2f2: 29 dd mov.l 0x8c00e398,r13 ! 0xacde0000 ; idx 8c00e2f4: 00 e4 mov #0,r4 ; fileptr = 0 8c00e2f6: 62 1f mov.l r6,@(8,r15) 8c00e2f8: 43 62 mov r4,r2 8c00e2fa: 01 45 shlr r5 8c00e2fc: 52 32 cmp/hs r5,r2 ; loop i (r4) up to number of slices 8c00e2fe: 06 8d bt.s 0x8c00e30e 8c00e300: 42 2f mov.l r4,@r15 8c00e302: 43 60 mov r4,r0 8c00e304: 00 40 shll r0 8c00e306: 45 0d mov.w r4,@(r0,r13) ; idx[i] = i 8c00e308: 01 74 add #1,r4 8c00e30a: 52 34 cmp/hs r5,r4 8c00e30c: f9 8b bf 0x8c00e302 8c00e30e: 53 6e mov r5,r14 ; loop i (r14) from number of 8c00e310: ff 7e add #-1,r14 ; slices-1 down to 0 8c00e312: 11 4e cmp/pz r14 8c00e314: 1c 8b bf 0x8c00e350 8c00e316: c1 bf bsr 0x8c00e29c ; my_rand(arg3) 8c00e318: f2 54 mov.l @(8,r15),r4 8c00e31a: e7 00 mul.l r14,r0 ; multiply result by i 8c00e31c: e3 6c mov r14,r12 8c00e31e: 00 4c shll r12 8c00e320: dc 3c add r13,r12 8c00e322: c1 64 mov.w @r12,r4 ; tmp = idx[i] 8c00e324: 1a 00 sts macl,r0 8c00e326: 03 65 mov r0,r5 8c00e328: 29 45 shlr16 r5 ; x = product >> 16 8c00e32a: 5f 65 exts.w r5,r5 8c00e32c: 5d 66 extu.w r5,r6 8c00e32e: f3 65 mov r15,r5 8c00e330: 00 46 shll r6 8c00e332: dc 36 add r13,r6 8c00e334: 61 63 mov.w @r6,r3 ; idx[i] = idx[x] 8c00e336: 31 2c mov.w r3,@r12 8c00e338: 41 26 mov.w r4,@r6 ; idx[x] = tmp 8c00e33a: c1 64 mov.w @r12,r4 8c00e33c: f1 53 mov.l @(4,r15),r3 8c00e33e: 4d 64 extu.w r4,r4 8c00e340: 08 44 shll2 r4 8c00e342: 08 44 shll2 r4 8c00e344: 00 44 shll r4 8c00e346: b9 bf bsr 0x8c00e2bc ; save(arg1+32*idx[i], &fileptr) 8c00e348: 3c 34 add r3,r4 8c00e34a: ff 7e add #-1,r14 8c00e34c: 11 4e cmp/pz r14 8c00e34e: e2 89 bt 0x8c00e316 8c00e350: 0c 7f add #12,r15 8c00e352: 16 4f lds.l @r15+,macl 8c00e354: 26 4f lds.l @r15+,pr 8c00e356: f6 6c mov.l @r15+,r12 8c00e358: f6 6d mov.l @r15+,r13 8c00e35a: 0b 00 rts 8c00e35c: f6 6e mov.l @r15+,r14 0x8c00e350 - offset 0x6350 in IP.BIN - save_file() but does so in memory, 0x8c00e39c is the actual size of 1ST_READ.BIN 8c00e35e: e6 2f mov.l r14,@-r15 8c00e360: d6 2f mov.l r13,@-r15 8c00e362: c6 2f mov.l r12,@-r15 8c00e364: b6 2f mov.l r11,@-r15 8c00e366: a6 2f mov.l r10,@-r15 8c00e368: 96 2f mov.l r9,@-r15 8c00e36a: 22 4f sts.l pr,@-r15 8c00e36c: f8 7f add #-8,r15 8c00e36e: 0b d3 mov.l 0x8c00e39c,r3 ! 0x200000 ; filesz 8c00e370: 20 e9 mov #32,r9 8c00e372: 0b dd mov.l 0x8c00e3a0,r13 ! 0xac010000 ; ptr 8c00e374: 32 2f mov.l r3,@r15 8c00e376: f2 63 mov.l @r15,r3 8c00e378: 0a de mov.l 0x8c00e3a4,r14 ! 0x200000 ; chunksz = 2 meg 8c00e37a: 06 da mov.l 0x8c00e394,r10 ! 0xace00000 ; temp area 8c00e37c: 3d 63 extu.w r3,r3 8c00e37e: 31 1f mov.l r3,@(4,r15) ; seed = filesz & 0xffff 8c00e380: 2b a0 bra 0x8c00e3da ; loop chunksz (r14) down to 32 8c00e382: 00 ec mov #0,r12 8c00e384: e3 6b mov r14,r11 8c00e386: 24 a0 bra 0x8c00e3d2 ; while filesz >= chunks 8c00e388: 09 4b shlr2 r11 [...] ; PC-relative data 8c00e3a8: f3 66 mov r15,r6 8c00e3aa: e3 65 mov r14,r5 8c00e3ac: 04 76 add #4,r6 8c00e3ae: 97 bf bsr 0x8c00e2e0 ; save_chunk(ptr, chunksz, &seed) 8c00e3b0: d3 64 mov r13,r4 8c00e3b2: 00 e2 mov #0,r2 8c00e3b4: d3 66 mov r13,r6 8c00e3b6: b2 32 cmp/hs r11,r2 8c00e3b8: c3 65 mov r12,r5 8c00e3ba: 06 8d bt.s 0x8c00e3ca ; loop i (r5) up to chunksz/4 8c00e3bc: c3 60 mov r12,r0 8c00e3be: ae 03 mov.l @(r0,r10),r3 ; read word from temp area 8c00e3c0: 01 75 add #1,r5 8c00e3c2: b2 35 cmp/hs r11,r5 8c00e3c4: 36 06 mov.l r3,@(r0,r6) ; write back to ptr+4*i 8c00e3c6: fa 8f bf.s 0x8c00e3be 8c00e3c8: 04 70 add #4,r0 8c00e3ca: f2 63 mov.l @r15,r3 8c00e3cc: ec 3d add r14,r13 ; ptr += chunksz 8c00e3ce: e8 33 sub r14,r3 ; filesz -= chunksz 8c00e3d0: 32 2f mov.l r3,@r15 8c00e3d2: f2 63 mov.l @r15,r3 8c00e3d4: e2 33 cmp/hs r14,r3 8c00e3d6: e7 89 bt 0x8c00e3a8 8c00e3d8: 01 4e shlr r14 ; chunksz >>= 1 8c00e3da: 92 3e cmp/hs r9,r14 8c00e3dc: d2 89 bt 0x8c00e384 8c00e3de: 08 7f add #8,r15 8c00e3e0: 26 4f lds.l @r15+,pr 8c00e3e2: f6 69 mov.l @r15+,r9 8c00e3e4: f6 6a mov.l @r15+,r10 8c00e3e6: f6 6b mov.l @r15+,r11 8c00e3e8: f6 6c mov.l @r15+,r12 8c00e3ea: f6 6d mov.l @r15+,r13 8c00e3ec: 0b 00 rts 8c00e3ee: f6 6e mov.l @r15+,r14 0x8c00e35e is called from 0x8c00e1ea, just before the jump to 0xac010000 which starts 1ST_READ.BIN.