Used ctypes to access functions in BNCSUtil, just finished the ones used for checkrevision. More will be ported as I complete them (watch this post).
from ctypes import *
from struct import *
platformDict = { 'NIX':0x01, 'WIN32':0x01, 'PMAC':0x02, 'XMAC':0x03 }
bncsutil = windll.LoadLibrary('./bncsutil.dll')
#checkrevision functions
def extractMPQNumber(mpqName):
return bncsutil.extractMPQNumber(mpqName)
def checkRevision(formula, hashFiles, mpqNumber):
#Make sure hashFiles is a list - if it isn't, fail.
if len(hashFiles) <> 3: return 0
checkSum = create_string_buffer('\000' * 10) #mutable memory block
if (bncsutil.checkRevisionFlat(formula, hashFiles[0], hashFiles[1],
hashFiles[2], mpqNumber, checkSum) == True):
#unpack the checksum, return first value of tuple
return unpack('L', checkSum.value)[0]
else:
#failed
return 0
def getExeInfo(exe):
size = 256
infoString = create_string_buffer(256)
version = create_string_buffer('\000' * 10)
result = bncsutil.getExeInfo(exe, infoString, size, version, platformDict['WIN32'])
while result > size:
if size > 1024:
return 0
else:
size = size + 256
infoString = create_string_buffer(size)
result = bncsutil.getExeInfo(exe, infoString, size, version, platformDict['WIN32'])
version = unpack('L', version.value)[0] #unpack version
return [version, infoString.value] #return version and info as a list
#ols functions
def doubleHashPassword( password, cToken, sToken):
dHash = create_string_buffer(20)
bncsutil.doubleHashPassword(password, cToken, sToken, dHash)
return dHash.value
def hashPassword(password):
pHash = create_string_buffer(20)
bncsutil.hashPassword(password, pHash)
return pHash.value
#sha1 function
def calcHashBuf(data):
dataLen = len(data)
dHash = create_string_buffer(20)
bncsutil.calcHashBuf(data, dataLen, dHash)
return dHash.value
#key decoding
def decodeCDKey(cdkey):
bncsutil.kd_create(cdkey, len(cdkey))
return decoder
def quickDecode(cdkey, cToken, sToken):
pdtValue = create_string_buffer('\000' * 10)
pvtValue = create_string_buffer('\000' * 10)
keyHash = create_string_buffer(20)
if (bncsutil.kd_quick(cdkey, cToken, sToken,
pdtValue, pvtValue, keyHash, 20)) == 0:
return 0 #failed to decode cdkey
else:
#returns the product value, private value,
# and hashed cdkey in a list
return [pdtValue, pvtValue, keyHash]
def calcKeyHash(decoder, cToken, sToken):
keyhash = bncsutil.kd_calculateHash(decoder, cToken, sToken)
return unpack('L', decoder.value)[0]
def getKeyHash(decoder, hashLength, keyHash):
keyHash = create_string_buffer(hashLength)
bncsutil.kd_getHash(decoder, keyHash)
return unpack('L', keyHash.value)[0]
def getValues(decoder):
#product and private values
pdtValue = unpack('L', bncsutil.kd_product(decoder).value)
pvtValue = unpack('L', bncsutil.kd_val1(decoder).value)
return (pdtValue, pvtValue)
I decided to remove the use of classes to seperate the different functions - it cleaned up the code and made it easier to access the functions without needing to initialize anything.
However, the keydecoding functions don't work - for some odd reason, the DLL attempts to read/write something it shouldn't be.
In case shadypalm88 looks at this:
traceback:
Traceback (most recent call last):
File "C:\Projects\bot-python\bncsutil.py", line 98, in -toplevel-
decoder = decodeCDKey('-------------')
File "C:\Projects\bot-python\bncsutil.py", line 74, in decodeCDKey
bncsutil.kd_create(cdkey, len(cdkey))
WindowsError: exception: access violation writing 0x00000010
code:
def decodeCDKey(cdkey):
decoder = bncsutil.kd_create(cdkey, len(cdkey))
return decoder
Post if you find out why its doing that or if you can fix it.
Edit: In the meantime, I wrote a function (quickdecode) that utilizes kd_quick().
MyndFyre edit: removed your CD key
http://starship.python.net/crew/theller/ctypes/tutorial.html
I believe you need to pass a pointer (byref) to a byte array.
That is, I think you probably have to pass the result of create_string_buffer rather than an actual string. In addition, you might have to wrap it in ctypes.byref(), though I'm not sure. Give it a shot, see if it works.
Quote from: Banana fanna fo fanna on July 13, 2006, 01:14 PM
That is, I think you probably have to pass the result of create_string_buffer rather than an actual string. In addition, you might have to wrap it in ctypes.byref(), though I'm not sure. Give it a shot, see if it works.
Doesn't help, I tried:
def decodeCDKey(cdkey):
cdkey = create_string_buffer(cdkey)
decoder = bncsutil.kd_create(cdkey, 13)
return decoder
I'm not allowed to use Byref(), since it requires an integer and the cdkey is thirteen digits in length.
I've come to think kd_create() is broken - in the VB6 example, shadypalm88 uses kd_quick(), but uses kd_create() in the previous version-/example.