Skip to content

Commit fc7c967

Browse files
zoogiezoogie
authored andcommitted
2.1
1 parent 462aecc commit fc7c967

File tree

5 files changed

+487
-64
lines changed

5 files changed

+487
-64
lines changed

bfCL

seedminer/saves/lfcs.dat

1.23 KB
Binary file not shown.

seedminer/saves/lfcs_new.dat

976 Bytes
Binary file not shown.

seedminer/seedminer_launcher.py

Lines changed: 83 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
from __future__ import print_function
2-
from __future__ import division
3-
import os,sys,struct,glob
4-
from binascii import hexlify, unhexlify
2+
import os,sys,struct,glob,urllib2
53

64
#don't change this mid brute force - can be different amount multiple computers - powers of two recommended for even distribution of workload 1 2 4 8 etc.
75
process_count=4
@@ -21,16 +19,11 @@
2119
err_correct=0
2220

2321
def int16bytes(n):
24-
if sys.version_info[0] > 2:
25-
# Python 3
26-
return n.to_bytes(16, 'big')
27-
else:
28-
# Python 2
29-
s=b""
30-
for i in range(16):
31-
s=chr(n & 0xFF)+s
32-
n=n>>8
33-
return s
22+
s=""
23+
for i in range(16):
24+
s=chr(n & 0xFF)+s
25+
n=n>>8
26+
return s
3427

3528
def expand():
3629
for i in range(1,len(lfcs)):
@@ -82,20 +75,22 @@ def getMsed3Estimate(n,isNew):
8275
xl=(fc[i]-fc[i-1])
8376
y=ft[i-1]
8477
yl=(ft[i]-ft[i-1])
85-
ys=((xs*yl)//xl)+y
78+
ys=((xs*yl)/xl)+y
8679
err_correct=ys
87-
return ((n//5)-ys) | newbit
80+
return ((n/5)-ys) | newbit
8881

89-
return ((n//5)-ft[ft_size-1]) | newbit
82+
return ((n/5)-ft[ft_size-1]) | newbit
9083

9184
def mii_gpu():
9285
from Cryptodome.Cipher import AES
9386

9487
nk31=0x59FC817E6446EA6190347B20E9BDCE52
9588
with open("input.bin", "rb") as f:
9689
enc=f.read()
97-
98-
nonce=enc[:8]+b"\x00"*4
90+
if(len(enc) != 0x70):
91+
print("Error: input.bin is invalid size (likely QR -> input.bin conversion issue)")
92+
sys.exit(0)
93+
nonce=enc[:8]+"\x00"*4
9994
cipher = AES.new(int16bytes(nk31), AES.MODE_CCM, nonce )
10095
dec=cipher.decrypt(enc[8:0x60])
10196
nonce=nonce[:8]
@@ -108,16 +103,16 @@ def mii_gpu():
108103
else:
109104
print("Error: need to specify new|old movable.sed")
110105
sys.exit(0)
111-
model_str=b""
112-
start_lfcs_old=0x0B000000//2
113-
start_lfcs_new=0x05000000//2
106+
model_str=""
107+
start_lfcs_old=0x0B000000/2
108+
start_lfcs_new=0x05000000/2
114109
start_lfcs=0
115110
year=0
116111
if(len(sys.argv)==4):
117112
year=int(sys.argv[3])
118113

119114
if(model=="old"):
120-
model_str=b"\x00\x00"
115+
model_str="\x00\x00"
121116
if (year==2011):
122117
start_lfcs_old=0x01000000
123118
elif(year==2012):
@@ -137,7 +132,7 @@ def mii_gpu():
137132
start_lfcs=start_lfcs_old
138133

139134
elif(model=="new"):
140-
model_str=b"\x02\x00"
135+
model_str="\x02\x00"
141136
if (year==2014):
142137
start_lfcs_new=0x00800000
143138
elif (year==2015):
@@ -150,7 +145,7 @@ def mii_gpu():
150145
print("Year 2014-2017 not entered so beginning at lfcs midpoint "+hex(start_lfcs_new))
151146
start_lfcs=start_lfcs_new
152147
start_lfcs=endian4(start_lfcs)
153-
command="bfcl lfcs %08X %s %s %08X" % (start_lfcs, hexlify(model_str).decode('ascii'), hexlify(final[4:4+8]).decode('ascii'), endian4(offset_override))
148+
command="bfcl lfcs %08X %s %s %08X" % (start_lfcs, model_str.encode('hex'), final[4:4+8].encode('hex'), endian4(offset_override))
154149
print(command)
155150
os.system(command)
156151

@@ -159,7 +154,7 @@ def generate_part2():
159154
with open("saves/lfcs.dat", "rb") as f:
160155
buf=f.read()
161156

162-
lfcs_len=len(buf)//8
157+
lfcs_len=len(buf)/8
163158
err_correct=0
164159

165160
for i in range(lfcs_len):
@@ -171,7 +166,7 @@ def generate_part2():
171166
with open("saves/lfcs_new.dat", "rb") as f:
172167
buf=f.read()
173168

174-
lfcs_new_len=len(buf)//8
169+
lfcs_new_len=len(buf)/8
175170

176171
for i in range(lfcs_new_len):
177172
lfcs_new.append(struct.unpack("<i",buf[i*8:i*8+4])[0])
@@ -181,12 +176,12 @@ def generate_part2():
181176

182177
isNew=False
183178
msed3=0
184-
noobtest=b"\x00"*0x20
179+
noobtest="\x00"*0x20
185180
with open("movable_part1.sed", "rb") as f:
186181
seed=f.read()
187182
if(noobtest in seed[0x10:0x30]):
188183
print("Error: ID0 has been left blank, please add an ID0")
189-
print("Ex: python %s id0 abcdef0123456789abcdef0123456789" % (sys.argv[0]))
184+
print("Ex: python %s id0 abcdef012345EXAMPLEdef0123456789" % (sys.argv[0]))
190185
sys.exit(0)
191186
if(noobtest[:4] in seed[:4]):
192187
print("Error: LFCS has been left blank, did you do a complete two-way friend code exchange before dumping friendlist?")
@@ -195,10 +190,10 @@ def generate_part2():
195190
print("Error: movable_part1.sed is not 4KB")
196191
sys.exit(0)
197192

198-
if seed[4:5]==b"\x02":
193+
if seed[4:5]=="\x02":
199194
print("New3DS msed")
200195
isNew=True
201-
elif seed[4:5]==b"\x00":
196+
elif seed[4:5]=="\x00":
202197
print("Old3DS msed - this can happen on a New3DS")
203198
isNew=False
204199
else:
@@ -212,51 +207,47 @@ def generate_part2():
212207
msed3=getMsed3Estimate(bytes2int(seed[0:4]),isNew)
213208

214209
offset=0x10
215-
hash_final=b""
210+
hash_final=""
216211
for i in range(64):
217212
try:
218-
hash=unhexlify(seed[offset:offset+0x20])
213+
hash=seed[offset:offset+0x20].decode("hex")
219214
except:
220215
break
221216
hash_single=byteSwap4(hash[0:4])+byteSwap4(hash[4:8])+byteSwap4(hash[8:12])+byteSwap4(hash[12:16])
222-
print("ID0 hash "+str(i)+": "+hexlify(hash_single).decode('ascii'))
217+
print("ID0 hash "+str(i)+": "+hash_single.encode('hex'))
223218
hash_final+=hash_single
224219
offset+=0x20
225220

226221
print("Hash total: "+str(i))
227222
part2=seed[0:12]+int2bytes(msed3)+hash_final
228223

229224
pad=0x1000-len(part2)
230-
part2+=b"\x00"*pad
225+
part2+="\x00"*pad
231226

232227
with open("movable_part2.sed", "wb") as f:
233228
f.write(part2)
234229
print("movable_part2.sed generation success")
235230

236231
def hash_clusterer():
237-
buf=b""
232+
buf=""
238233
hashcount=0
239234

240-
with open("movable_part1.sed", "rb") as f:
241-
file=f.read()
242-
with open("movable_part1.sed.backup", "wb") as f:
243-
f.write(file)
244-
245-
trim=0
246-
try:
247-
trim=file.index(b"\x00"*0x40)
248-
if(trim<0x10):
249-
trim=0x10
250-
file=file[:trim]
251-
except:
252-
pass
253-
254235
if(len(sys.argv)==3):
255236
dirs=[]
256237
dirs.append(sys.argv[2])
257238
else:
258239
dirs=glob.glob("*")
259-
240+
241+
try:
242+
with open("movable_part1.sed", "rb") as f:
243+
file=f.read()
244+
except:
245+
print("movable_part1.sed not found, generating a new one")
246+
print("don't forget to add an lfcs to it!")
247+
with open("movable_part1.sed", "wb") as f:
248+
file="\x00"*0x1000
249+
f.write(file)
250+
260251
for i in dirs:
261252
try:
262253
print(i,end='')
@@ -274,16 +265,22 @@ def hash_clusterer():
274265
if(hashcount>1):
275266
print("Too many ID0 dirs! (%d)\nMove the ones your 3ds isn't using!" % (hashcount))
276267
sys.exit(0)
277-
268+
278269
if(hashcount==1):
279270
print("Hash added!")
280271
else:
281272
print("No hashes added!")
273+
sys.exit(0)
274+
275+
with open("movable_part1.sed.backup", "wb") as f:
276+
f.write(file)
277+
278+
file=file[:0x10]
282279
pad_len=0x1000-len(file+buf)
283-
pad=b"\x00"*pad_len
280+
pad="\x00"*pad_len
284281
with open("movable_part1.sed", "wb") as f:
285282
f.write(file+buf+pad)
286-
print("There are now %d ID0 hashes in your movable_part1.sed!" % ((len(file+buf)//0x20)))
283+
print("There are now %d ID0 hashes in your movable_part1.sed!" % ((len(file+buf)/0x20)))
287284
print("Done!")
288285

289286
def do_cpu():
@@ -299,7 +296,7 @@ def do_cpu():
299296
address_begin=0
300297
address_end=MAX
301298

302-
address_space=MAX//number_of_computers
299+
address_space=MAX/number_of_computers
303300

304301
for i in range(number_of_computers):
305302
if(which_computer_is_this==i):
@@ -314,7 +311,7 @@ def do_cpu():
314311
print("")
315312

316313
process_space=address_end-address_begin
317-
process_size=process_space//process_count
314+
process_size=process_space/process_count
318315

319316
for i in range(process_count):
320317
process_begin=address_begin+(process_size*i)
@@ -329,35 +326,51 @@ def do_cpu():
329326
def do_gpu():
330327
with open("movable_part2.sed", "rb") as f:
331328
buf=f.read()
332-
keyy=hexlify(buf[:16]).decode('ascii')
333-
ID0=hexlify(buf[16:32]).decode('ascii')
329+
keyy=buf[:16].encode('hex')
330+
ID0=buf[16:32].encode('hex')
334331
command="bfcl msky %s %s %08X" % (keyy,ID0, endian4(offset_override))
335332
print(command)
336333
os.system(command)
334+
335+
def download(url, dest):
336+
try:
337+
response = urllib2.urlopen(url)
338+
html = response.read()
339+
data=""
340+
with open(dest, "rb") as f:
341+
data=f.read()
342+
if(data != html):
343+
with open(dest, "wb") as f:
344+
f.write(html)
345+
print("Updating "+dest+" success!")
346+
else:
347+
print(dest+" is already up-to-date!")
348+
except:
349+
print("Error updating "+dest)
350+
351+
def update_db():
352+
download("https://github.com/zoogie/seedminer/blob/master/seedminer/saves/lfcs.dat?raw=true","saves/lfcs.dat")
353+
download("https://github.com/zoogie/seedminer/blob/master/seedminer/saves/lfcs_new.dat?raw=true","saves/lfcs_new.dat")
337354

338355
def error_print():
339356
print("\nCommand line error")
340357
print("Usage:")
341-
print("python %s cpu|gpu|id0|mii old|mii new [# cpu processes] [ID0 hash] [year 3ds built]" % (sys.argv[0]))
358+
print("python %s cpu|gpu|id0|mii old|mii new|update-db [# cpu processes] [ID0 hash] [year 3ds built]" % (sys.argv[0]))
342359
print("Examples:")
343360
print("python %s cpu 4" % (sys.argv[0]))
344361
print("python %s gpu" % (sys.argv[0]))
345362
print("python %s id0 abcdef012345EXAMPLEdef0123456789" % (sys.argv[0]))
346363
print("python %s mii new 2017" % (sys.argv[0]))
347364
print("python %s mii old 2011" % (sys.argv[0]))
348365
print("python %s mii old" % (sys.argv[0]))
366+
print("python %s update-db" % (sys.argv[0]))
349367
#---------------------------------------------------------------------------
350368
#command handler
351369
#---------------------------------------------------------------------------
352370
abspath = os.path.abspath(__file__)
353371
dname = os.path.dirname(abspath)
354372
os.chdir(dname)
355373

356-
# "SEEDMINER_ALLOW3" is checked to allow Python 3 during testing.
357-
# It should be removed when 3 is ready for everyone to use.
358-
if(sys.version_info[0] != 2 and os.environ.get('SEEDMINER_ALLOW3') != '1'):
359-
print("For the highest levels of customer safety and satisfaction, please use Python 2")
360-
sys.exit(0)
361374
if(len(sys.argv) < 2 or len(sys.argv) > 4):
362375
error_print()
363376
sys.exit(0)
@@ -379,6 +392,13 @@ def error_print():
379392
elif(sys.argv[1].lower()=="mii"):
380393
print("MII selected")
381394
mii_gpu()
395+
generate_part2()
396+
offset_override=0
397+
do_gpu()
398+
sys.exit(0)
399+
elif(sys.argv[1].lower()=="update-db"):
400+
print("Update msed_data selected")
401+
update_db()
382402
sys.exit(0)
383403
else:
384404
error_print()

0 commit comments

Comments
 (0)