mirror of https://github.com/hak5/ToorChat.git
Initial import, far from there
parent
eca5e0475d
commit
0a43947937
|
@ -0,0 +1,39 @@
|
||||||
|
|
||||||
|
class ToorChatProtocol():
|
||||||
|
''' This is a class to allow for easy of use with anything to do with messaging '''
|
||||||
|
def __init__(self, device):
|
||||||
|
self.PACKET_START = "\xFF\xDE\xAD\xFF"
|
||||||
|
self.PACKET_END = "\xFF\xBE\xEF\xFF"
|
||||||
|
self.device = device
|
||||||
|
|
||||||
|
def send_message(cls, message = "", user = None):
|
||||||
|
''' This is used to send a simple message over the toorchat protocol '''
|
||||||
|
msg = ToorChatMessage(message, user)
|
||||||
|
self.device.RFxmit(msg)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_packet_start(cls):
|
||||||
|
return "\xFF\xDE\xAD\xFF"
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_packet_end(cls):
|
||||||
|
return "\xFF\xBE\xEF\xFF"
|
||||||
|
|
||||||
|
class ToorChatMessage():
|
||||||
|
''' This is a simple Message object wrapper to make things cleaner '''
|
||||||
|
|
||||||
|
def __init__(self, message = "", user = None):
|
||||||
|
self.start = ToorChatProtocol.get_packet_start()
|
||||||
|
self.xid = self.get_random_xid()
|
||||||
|
if user != None:
|
||||||
|
self.user = user
|
||||||
|
else:
|
||||||
|
self.user = "\x00"*32
|
||||||
|
self.data = message
|
||||||
|
self.end = ToorChatProtocol.get_packet_end()
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.start + self.xid + self.user + self.data + self.end
|
||||||
|
|
||||||
|
def to_string(self):
|
||||||
|
return self.__str__()
|
|
@ -0,0 +1,163 @@
|
||||||
|
#!/usr/bin/env ipython
|
||||||
|
from chipcon_nic import *
|
||||||
|
|
||||||
|
RFCAT_START_SPECAN = 0x40
|
||||||
|
RFCAT_STOP_SPECAN = 0x41
|
||||||
|
|
||||||
|
class RfCat(FHSSNIC):
|
||||||
|
def RFdump(self, msg="Receiving", maxnum=100, timeoutms=1000):
|
||||||
|
try:
|
||||||
|
for x in xrange(maxnum):
|
||||||
|
y, t = self.RFrecv(timeoutms)
|
||||||
|
print "(%5.3f) %s: %s" % (t, msg, y.encode('hex'))
|
||||||
|
except ChipconUsbTimeoutException:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def scan(self, basefreq=902e6, inc=250e3, count=104, delaysec=2, drate=38400, lowball=1):
|
||||||
|
'''
|
||||||
|
scan for signal over a range of frequencies
|
||||||
|
'''
|
||||||
|
self.RFdump("Clearing")
|
||||||
|
self.lowball(lowball)
|
||||||
|
self.setMdmDRate(drate)
|
||||||
|
print "Scanning range: "
|
||||||
|
while not keystop():
|
||||||
|
try:
|
||||||
|
print
|
||||||
|
for freq in xrange(int(basefreq), int(basefreq+(inc*count)), int(inc)):
|
||||||
|
print "Scanning for frequency %d..." % freq
|
||||||
|
self.setFreq(freq)
|
||||||
|
self.RFdump(timeoutms=delaysec*1000)
|
||||||
|
if keystop():
|
||||||
|
break
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
print "Please press <enter> to stop"
|
||||||
|
|
||||||
|
sys.stdin.read(1)
|
||||||
|
self.lowballRestore()
|
||||||
|
|
||||||
|
def specan(self, basefreq=902e6, inc=250e3, count=104):
|
||||||
|
freq, delta = self._doSpecAn(basefreq, inc, count)
|
||||||
|
|
||||||
|
import rflib.ccspecan as rfspecan
|
||||||
|
if not hasattr(self, "_qt_app") or self._qt_app is None:
|
||||||
|
self._qt_app = rfspecan.QtGui.QApplication([])
|
||||||
|
|
||||||
|
fhigh = freq + (delta*(count+1))
|
||||||
|
|
||||||
|
window = rfspecan.Window(self, freq, fhigh, delta, 0)
|
||||||
|
window.show()
|
||||||
|
self._qt_app.exec_()
|
||||||
|
|
||||||
|
def _doSpecAn(self, basefreq, inc, count):
|
||||||
|
'''
|
||||||
|
store radio config and start sending spectrum analysis data
|
||||||
|
'''
|
||||||
|
if count>255:
|
||||||
|
raise Exception("sorry, only 255 samples per pass... (count)")
|
||||||
|
self.getRadioConfig()
|
||||||
|
self._specan_backup_radiocfg = self.radiocfg
|
||||||
|
|
||||||
|
self.setFreq(basefreq)
|
||||||
|
self.setMdmChanSpc(inc)
|
||||||
|
|
||||||
|
freq, fbytes = self.getFreq()
|
||||||
|
delta = self.getMdmChanSpc()
|
||||||
|
|
||||||
|
self.send(APP_NIC, RFCAT_START_SPECAN, "%c" % (count) )
|
||||||
|
return freq, delta
|
||||||
|
|
||||||
|
def _stopSpecAn(self):
|
||||||
|
'''
|
||||||
|
stop sending rfdata and return radio to original config
|
||||||
|
'''
|
||||||
|
self.send(APP_NIC, RFCAT_STOP_SPECAN, '')
|
||||||
|
self.radiocfg = self._specan_backup_radiocfg
|
||||||
|
self.setRadioConfig()
|
||||||
|
|
||||||
|
|
||||||
|
def rf_configure(*args, **k2args):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def rf_redirection(self, fdtup):
|
||||||
|
if len(fdtup)>1:
|
||||||
|
fd0i, fd0o = fdtup
|
||||||
|
else:
|
||||||
|
fd0i, = fdtup
|
||||||
|
fd0o, = fdtup
|
||||||
|
|
||||||
|
fdsock = False # socket or fileio?
|
||||||
|
if hasattr(fd0i, 'recv'):
|
||||||
|
fdsock = True
|
||||||
|
|
||||||
|
while True:
|
||||||
|
x,y,z = select.select([fd0i ], [], [], .1)
|
||||||
|
#if self._pause:
|
||||||
|
# continue
|
||||||
|
|
||||||
|
if fd0i in x:
|
||||||
|
if fdsock:
|
||||||
|
data = fd0i.recv(self.max_packet_size)
|
||||||
|
else:
|
||||||
|
data = fd0i.read(self.max_packet_size)
|
||||||
|
|
||||||
|
if not len(data): # terminated socket
|
||||||
|
break
|
||||||
|
|
||||||
|
self.RFxmit(data)
|
||||||
|
|
||||||
|
try:
|
||||||
|
data = self.RFrecv(0)
|
||||||
|
if fdsock:
|
||||||
|
fd0o.sendall(data)
|
||||||
|
else:
|
||||||
|
fd0o.write(data)
|
||||||
|
except ChipconUsbTimeoutException:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def cleanupInteractiveAtExit():
|
||||||
|
try:
|
||||||
|
if d.getDebugCodes():
|
||||||
|
d.setModeIDLE()
|
||||||
|
pass
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
def interactive(idx=0, DongleClass=RfCat, intro=''):
|
||||||
|
global d
|
||||||
|
import rflib.chipcon_nic as rfnic
|
||||||
|
import atexit
|
||||||
|
|
||||||
|
d = DongleClass(idx=idx)
|
||||||
|
d.setModeRX() # this puts the dongle into receive mode
|
||||||
|
atexit.register(cleanupInteractiveAtExit)
|
||||||
|
|
||||||
|
gbls = globals()
|
||||||
|
lcls = locals()
|
||||||
|
|
||||||
|
try:
|
||||||
|
import IPython.Shell
|
||||||
|
ipsh = IPython.Shell.IPShell(argv=[''], user_ns=lcls, user_global_ns=gbls)
|
||||||
|
print intro
|
||||||
|
ipsh.mainloop(intro)
|
||||||
|
|
||||||
|
except ImportError, e:
|
||||||
|
try:
|
||||||
|
from IPython.frontend.terminal.interactiveshell import TerminalInteractiveShell
|
||||||
|
ipsh = TerminalInteractiveShell()
|
||||||
|
ipsh.user_global_ns.update(gbls)
|
||||||
|
ipsh.user_global_ns.update(lcls)
|
||||||
|
ipsh.autocall = 2 # don't require parenthesis around *everything*. be smart!
|
||||||
|
ipsh.mainloop(intro)
|
||||||
|
except ImportError, e:
|
||||||
|
print e
|
||||||
|
shell = code.InteractiveConsole(gbls)
|
||||||
|
shell.interact(intro)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
idx = 0
|
||||||
|
if len(sys.argv) > 1:
|
||||||
|
idx = int(sys.argv.pop())
|
||||||
|
|
||||||
|
interactive(idx)
|
|
@ -0,0 +1,347 @@
|
||||||
|
import struct
|
||||||
|
|
||||||
|
def shiftString(string, bits):
|
||||||
|
carry = 0
|
||||||
|
news = []
|
||||||
|
for x in xrange(len(string)-1):
|
||||||
|
newc = ((ord(string[x]) << bits) + (ord(string[x+1]) >> (8-bits))) & 0xff
|
||||||
|
news.append("%c"%newc)
|
||||||
|
newc = (ord(string[-1])<<bits) & 0xff
|
||||||
|
news.append("%c"%newc)
|
||||||
|
return "".join(news)
|
||||||
|
|
||||||
|
def findDword(byts, inverted=False):
|
||||||
|
possDwords = []
|
||||||
|
# find the preamble (if any)
|
||||||
|
while True:
|
||||||
|
sbyts = byts
|
||||||
|
pidx = byts.find("\xaa\xaa")
|
||||||
|
if pidx == -1:
|
||||||
|
pidx = byts.find("\x55\x55")
|
||||||
|
byts = shiftString(byts,1)
|
||||||
|
|
||||||
|
if pidx == -1:
|
||||||
|
return possDwords
|
||||||
|
|
||||||
|
# chop off the nonsense before the preamble
|
||||||
|
sbyts = byts[pidx:]
|
||||||
|
#print "sbyts: %s" % repr(sbyts)
|
||||||
|
|
||||||
|
# find the definite end of the preamble (ie. it may be sooner, but we know this is the end)
|
||||||
|
while (sbyts[0] == '\xaa' and len(sbyts)>2):
|
||||||
|
sbyts = sbyts[1:]
|
||||||
|
|
||||||
|
#print "sbyts: %s" % repr(sbyts)
|
||||||
|
# now we look at the next 16 bits to narrow the possibilities to 8
|
||||||
|
# at this point we have no hints at bit-alignment aside from 0xaa vs 0x55
|
||||||
|
dwbits, = struct.unpack(">H", sbyts[:2])
|
||||||
|
#print "sbyts: %s" % repr(sbyts)
|
||||||
|
#print "dwbits: %s" % repr(dwbits)
|
||||||
|
if len(sbyts)>=3:
|
||||||
|
bitcnt = 0
|
||||||
|
# bits1 = aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb
|
||||||
|
# bits2 = bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
|
||||||
|
bits1, = struct.unpack(">H", sbyts[:2])
|
||||||
|
bits1 = bits1 | (ord('\xaa') << 16)
|
||||||
|
bits1 = bits1 | (ord('\xaa') << 24)
|
||||||
|
bits1 <<= 8
|
||||||
|
bits1 |= (ord(sbyts[2]) )
|
||||||
|
#print "bits: %x" % (bits1)
|
||||||
|
|
||||||
|
bit = (5 * 8) - 2 # bytes times bits/byte #FIXME: MAGIC NUMBERS!?
|
||||||
|
while (bits1 & (3<<bit) == (2<<bit)):
|
||||||
|
bit -= 2
|
||||||
|
#print "bit = %d" % bit
|
||||||
|
bits1 >>= (bit-16)
|
||||||
|
#while (bits1 & 0x30000 != 0x20000): # now we align the end of the 101010 pattern with the beginning of the dword
|
||||||
|
# bits1 >>= 2
|
||||||
|
#print "bits: %x" % (bits1)
|
||||||
|
|
||||||
|
for frontbits in xrange((0,1)[inverted], 17, 2):
|
||||||
|
poss = (bits1 >> frontbits) & 0xffff
|
||||||
|
if not poss in possDwords:
|
||||||
|
possDwords.append(poss)
|
||||||
|
byts = byts[pidx+1:]
|
||||||
|
|
||||||
|
return possDwords
|
||||||
|
|
||||||
|
def findDwordDoubled(byts):
|
||||||
|
possDwords = []
|
||||||
|
# find the preamble (if any)
|
||||||
|
bitoff = 0
|
||||||
|
pidx = byts.find("\xaa\xaa")
|
||||||
|
if pidx == -1:
|
||||||
|
pidx = byts.find("\55\x55")
|
||||||
|
bitoff = 1
|
||||||
|
if pidx == -1:
|
||||||
|
return []
|
||||||
|
|
||||||
|
# chop off the nonsense before the preamble
|
||||||
|
byts = byts[pidx:]
|
||||||
|
|
||||||
|
# find the definite end of the preamble (ie. it may be sooner, but we know this is the end)
|
||||||
|
while (byts[0] == ('\xaa', '\x55')[bitoff] and len(byts)>2):
|
||||||
|
byts = byts[1:]
|
||||||
|
|
||||||
|
# now we look at the next 16 bits to narrow the possibilities to 8
|
||||||
|
# at this point we have no hints at bit-alignment
|
||||||
|
dwbits, = struct.unpack(">H", byts[:2])
|
||||||
|
if len(byts)>=5:
|
||||||
|
bitcnt = 0
|
||||||
|
# bits1 = aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb
|
||||||
|
# bits2 = bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
|
||||||
|
bits1, = struct.unpack(">H", byts[:2])
|
||||||
|
bits1 = bits1 | (ord(('\xaa','\x55')[bitoff]) << 16)
|
||||||
|
bits1 = bits1 | (ord(('\xaa','\x55')[bitoff]) << 24)
|
||||||
|
bits1 <<= 8
|
||||||
|
bits1 |= (ord(byts[2]) )
|
||||||
|
bits1 >>= bitoff
|
||||||
|
|
||||||
|
bits2, = struct.unpack(">L", byts[:4])
|
||||||
|
bits2 <<= 8
|
||||||
|
bits2 |= (ord(byts[4]) )
|
||||||
|
bits2 >>= bitoff
|
||||||
|
|
||||||
|
|
||||||
|
frontbits = 0
|
||||||
|
for frontbits in xrange(16, 40, 2): #FIXME: if this doesn't work, try 16, then 18+frontbits
|
||||||
|
dwb1 = (bits1 >> (frontbits)) & 3
|
||||||
|
dwb2 = (bits2 >> (frontbits)) & 3
|
||||||
|
print "\tfrontbits: %d \t\t dwb1: %s dwb2: %s" % (frontbits, bin(bits1 >> (frontbits)), bin(bits2 >> (frontbits)))
|
||||||
|
if dwb2 != dwb1:
|
||||||
|
break
|
||||||
|
|
||||||
|
# frontbits now represents our unknowns... let's go from the other side now
|
||||||
|
for tailbits in xrange(16, -1, -2):
|
||||||
|
dwb1 = (bits1 >> (tailbits)) & 3
|
||||||
|
dwb2 = (bits2 >> (tailbits)) & 3
|
||||||
|
print "\ttailbits: %d\t\t dwb1: %s dwb2: %s" % (tailbits, bin(bits1 >> (tailbits)), bin(bits2 >> (tailbits)))
|
||||||
|
if dwb2 != dwb1:
|
||||||
|
tailbits += 2
|
||||||
|
break
|
||||||
|
|
||||||
|
# now, if we have a double syncword, iinm, tailbits + frontbits >= 16
|
||||||
|
print "frontbits: %d\t\t tailbits: %d, bits: %s " % (frontbits, tailbits, bin((bits2>>tailbits & 0xffffffff)))
|
||||||
|
if (frontbits + tailbits >= 16):
|
||||||
|
tbits = bits2 >> (tailbits&0xffff)
|
||||||
|
tbits &= (0xffffffff)
|
||||||
|
print "tbits: %x" % tbits
|
||||||
|
|
||||||
|
poss = tbits&0xffffffff
|
||||||
|
if poss not in possDwords:
|
||||||
|
possDwords.append(poss)
|
||||||
|
else:
|
||||||
|
pass
|
||||||
|
# FIXME: what if we *don't* have a double-sync word? then we stop at AAblah or 55blah and take the next word?
|
||||||
|
|
||||||
|
possDwords.reverse()
|
||||||
|
return possDwords
|
||||||
|
|
||||||
|
#def test():
|
||||||
|
|
||||||
|
def visBits(data):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def getBit(data, bit):
|
||||||
|
idx = bit / 8
|
||||||
|
bidx = bit % 8
|
||||||
|
char = data[idx]
|
||||||
|
return (ord(char)>>(7-bidx)) & 1
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def detectRepeatPatterns(data, size=64, minEntropy=.07):
|
||||||
|
#FIXME: convert strings to bit arrays before comparing.
|
||||||
|
c1 = 0
|
||||||
|
c2 = 0
|
||||||
|
d1 = 0
|
||||||
|
p1 = 0
|
||||||
|
mask = (1<<size) - 1
|
||||||
|
bitlen = 8*len(data)
|
||||||
|
|
||||||
|
while p1 < (bitlen-size-8):
|
||||||
|
d1 <<= 1
|
||||||
|
d1 |= getBit(data, p1)
|
||||||
|
d1 &= mask
|
||||||
|
#print bin(d1)
|
||||||
|
|
||||||
|
if c1 < (size):
|
||||||
|
p1 += 1
|
||||||
|
c1 += 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
d2 = 0
|
||||||
|
p2 = p1+size
|
||||||
|
while p2 < (bitlen):
|
||||||
|
d2 <<= 1
|
||||||
|
d2 |= getBit(data, p2)
|
||||||
|
d2 &= mask
|
||||||
|
#print bin(d2)
|
||||||
|
|
||||||
|
if c2 < (size):
|
||||||
|
p2 += 1
|
||||||
|
c2 += 1
|
||||||
|
continue
|
||||||
|
|
||||||
|
if d1 == d2 and d1 > 0:
|
||||||
|
s1 = p1 - size
|
||||||
|
s2 = p2 - size
|
||||||
|
print "s1: %d\t p1: %d\t " % (s1, p1)
|
||||||
|
print "s2: %d\t p2: %d\t " % (s2, p2)
|
||||||
|
# complete the pattern until the numbers differ or meet
|
||||||
|
while True:
|
||||||
|
p1 += 1
|
||||||
|
p2 += 1
|
||||||
|
#print "s1: %d\t p1: %d\t " % (s1, p1)
|
||||||
|
#print "s2: %d\t p2: %d\t " % (s2, p2)
|
||||||
|
if p2 >= bitlen:
|
||||||
|
break
|
||||||
|
|
||||||
|
b1 = getBit(data,p1)
|
||||||
|
b2 = getBit(data,p2)
|
||||||
|
|
||||||
|
if p1 == s2 or b1 != b2:
|
||||||
|
break
|
||||||
|
|
||||||
|
length = p1 - s1
|
||||||
|
c2 = 0
|
||||||
|
p2 -= size
|
||||||
|
|
||||||
|
bitSection, ent = bitSectString(data, s1, s1+length)
|
||||||
|
if ent > minEntropy:
|
||||||
|
print "success:"
|
||||||
|
print " * bit idx1: %4d (%4d bits) - '%s' %s" % (s1, length, bin(d1), bitSection.encode("hex"))
|
||||||
|
print " * bit idx2: %4d (%4d bits) - '%s'" % (s2, length, bin(d2))
|
||||||
|
#else:
|
||||||
|
# print " * idx1: %d - '%s' * idx2: %d - '%s'" % (p1, d1, p2, d2)
|
||||||
|
p2 += 1
|
||||||
|
p1 += 1
|
||||||
|
|
||||||
|
|
||||||
|
def bitSectString(string, startbit, endbit):
|
||||||
|
'''
|
||||||
|
bitsects a string... ie. chops out the bits from the middle of the string
|
||||||
|
returns the new string and the entropy (ratio of 0:1)
|
||||||
|
'''
|
||||||
|
ones = 0
|
||||||
|
zeros = 0
|
||||||
|
entropy = [zeros, ones]
|
||||||
|
|
||||||
|
s = ''
|
||||||
|
bit = startbit
|
||||||
|
|
||||||
|
Bidx = bit / 8
|
||||||
|
bidx = (bit % 8)
|
||||||
|
|
||||||
|
while bit < endbit:
|
||||||
|
|
||||||
|
byte1 = ord( string[Bidx] )
|
||||||
|
try:
|
||||||
|
byte2 = ord( string[Bidx+1] )
|
||||||
|
except IndexError:
|
||||||
|
byte2 = 0
|
||||||
|
|
||||||
|
byte = (byte1 << bidx) & 0xff
|
||||||
|
byte |= (byte2 >> (8-bidx))
|
||||||
|
#calculate entropy over the byte
|
||||||
|
for bi in range(8):
|
||||||
|
b = (byte>>bi) & 1
|
||||||
|
entropy[b] += 1
|
||||||
|
|
||||||
|
bit += 8
|
||||||
|
Bidx += 1
|
||||||
|
|
||||||
|
if bit > endbit:
|
||||||
|
diff = bit-endbit
|
||||||
|
mask = ~ ( (1<<diff) - 1 )
|
||||||
|
byte &= mask
|
||||||
|
|
||||||
|
s += chr(byte)
|
||||||
|
|
||||||
|
ent = (min(entropy)+1.0) / (max(entropy)+1)
|
||||||
|
#print "entropy: %f" % ent
|
||||||
|
return (s, ent)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def genBitArray(string, startbit, endbit):
|
||||||
|
'''
|
||||||
|
bitsects a string... ie. chops out the bits from the middle of the string
|
||||||
|
returns the new string and the entropy (ratio of 0:1)
|
||||||
|
'''
|
||||||
|
binStr, ent = bitSectString(string, startbit, endbit)
|
||||||
|
|
||||||
|
s = []
|
||||||
|
for byte in binStr:
|
||||||
|
byte = ord(byte)
|
||||||
|
for bitx in range(7, -1, -1):
|
||||||
|
bit = (byte>>bitx) & 1
|
||||||
|
s.append(bit)
|
||||||
|
|
||||||
|
return (s, ent)
|
||||||
|
|
||||||
|
|
||||||
|
chars_top = [
|
||||||
|
" ", #000
|
||||||
|
" ", #001
|
||||||
|
"^", #010
|
||||||
|
"/", #011
|
||||||
|
" ", #100
|
||||||
|
" ", #101
|
||||||
|
"\\",#110
|
||||||
|
"-", #111
|
||||||
|
]
|
||||||
|
|
||||||
|
chars_mid = [
|
||||||
|
" ", #000
|
||||||
|
"|", #001
|
||||||
|
"#", #010
|
||||||
|
" ", #011
|
||||||
|
"|", #100
|
||||||
|
"#", #101
|
||||||
|
" ", #110
|
||||||
|
" ", #110
|
||||||
|
]
|
||||||
|
|
||||||
|
chars_bot = [
|
||||||
|
"-", #000
|
||||||
|
"/", #001
|
||||||
|
" ", #010
|
||||||
|
" ", #011
|
||||||
|
"\\",#100
|
||||||
|
"V", #101
|
||||||
|
" ", #110
|
||||||
|
" ", #110
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def reprBitArray(bitAry, width=194):
|
||||||
|
top = []
|
||||||
|
mid = []
|
||||||
|
bot = []
|
||||||
|
|
||||||
|
arylen = len(bitAry)
|
||||||
|
# top line
|
||||||
|
#FIXME: UGGGGLY and kinda broken.
|
||||||
|
fraction = 1.0 * arylen/width
|
||||||
|
expand = [bitAry[int(x*fraction)] for x in xrange(width)]
|
||||||
|
|
||||||
|
for bindex in xrange(width):
|
||||||
|
bits = 0
|
||||||
|
if bindex>0:
|
||||||
|
bits += (expand[bindex-1]) << (2)
|
||||||
|
bits += (expand[bindex]) << (1)
|
||||||
|
if bindex < width-1:
|
||||||
|
bits += (expand[bindex+1])
|
||||||
|
|
||||||
|
top.append( chars_top[ bits ] )
|
||||||
|
mid.append( chars_mid[ bits ] )
|
||||||
|
bot.append( chars_bot[ bits ] )
|
||||||
|
|
||||||
|
tops = "".join(top)
|
||||||
|
mids = "".join(mid)
|
||||||
|
bots = "".join(bot)
|
||||||
|
return "\n".join([tops, mids, bots])
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,147 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
"""
|
||||||
|
#include<compiler.h>
|
||||||
|
/* ------------------------------------------------------------------------------------------------
|
||||||
|
* Interrupt Vectors
|
||||||
|
* ------------------------------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
#define RFTXRX_VECTOR 0 /* RF TX done / RX ready */
|
||||||
|
#define ADC_VECTOR 1 /* ADC End of Conversion */
|
||||||
|
#define URX0_VECTOR 2 /* USART0 RX Complete */
|
||||||
|
#define URX1_VECTOR 3 /* USART1 RX Complete */
|
||||||
|
#define ENC_VECTOR 4 /* AES Encryption/Decryption Complete */
|
||||||
|
#define ST_VECTOR 5 /* Sleep Timer Compare */
|
||||||
|
#define P2INT_VECTOR 6 /* Port 2 Inputs */
|
||||||
|
#define UTX0_VECTOR 7 /* USART0 TX Complete */
|
||||||
|
#define DMA_VECTOR 8 /* DMA Transfer Complete */
|
||||||
|
#define T1_VECTOR 9 /* Timer 1 (16-bit) Capture/Compare/Overflow */
|
||||||
|
#define T2_VECTOR 10 /* Timer 2 (MAC Timer) Overflow */
|
||||||
|
#define T3_VECTOR 11 /* Timer 3 (8-bit) Capture/Compare/Overflow */
|
||||||
|
#define T4_VECTOR 12 /* Timer 4 (8-bit) Capture/Compare/Overflow */
|
||||||
|
#define P0INT_VECTOR 13 /* Port 0 Inputs */
|
||||||
|
#define UTX1_VECTOR 14 /* USART1 TX Complete */
|
||||||
|
#define P1INT_VECTOR 15 /* Port 1 Inputs */
|
||||||
|
#define RF_VECTOR 16 /* RF General Interrupts */
|
||||||
|
#define WDT_VECTOR 17 /* Watchdog Overflow in Timer Mode */
|
||||||
|
|
||||||
|
SFR(P0, 0x80); // Port 0
|
||||||
|
SBIT(P0_0, 0x80, 0); // Port 0 bit 0
|
||||||
|
SBIT(P0_1, 0x80, 1); // Port 0 bit 1
|
||||||
|
SBIT(P0_2, 0x80, 2); // Port 0 bit 2
|
||||||
|
SBIT(P0_3, 0x80, 3); // Port 0 bit 3
|
||||||
|
SBIT(P0_4, 0x80, 4); // Port 0 bit 4
|
||||||
|
SBIT(P0_5, 0x80, 5); // Port 0 bit 5
|
||||||
|
SBIT(P0_6, 0x80, 6); // Port 0 bit 6
|
||||||
|
SBIT(P0_7, 0x80, 7); // Port 0 bit 7
|
||||||
|
|
||||||
|
SFR(SP, 0x81); // Stack Pointer
|
||||||
|
SFR(DPL0, 0x82); // Data Pointer 0 Low Byte
|
||||||
|
SFR(DPH0, 0x83); // Data Pointer 0 High Byte
|
||||||
|
SFR(DPL1, 0x84); // Data Pointer 1 Low Byte
|
||||||
|
SFR(DPH1, 0x85); // Data Pointer 1 High Byte
|
||||||
|
"""
|
||||||
|
import sys
|
||||||
|
|
||||||
|
|
||||||
|
def parseLines(lines):
|
||||||
|
defs = {}
|
||||||
|
incomment = False
|
||||||
|
for line in lines:
|
||||||
|
# find single-line comments
|
||||||
|
slc = line.find("//")
|
||||||
|
if (slc > -1):
|
||||||
|
line = line[:slc] + "#" + line[slc+2:]
|
||||||
|
# find /* */ comments
|
||||||
|
mlcs = line.find("/*")
|
||||||
|
mlce = line.find("*/")
|
||||||
|
if (mlcs>-1):
|
||||||
|
if (mlce>-1): # both are in this line
|
||||||
|
if (mlce>mlcs): # they are "together"
|
||||||
|
if (mlce >= len(line.strip())-3):
|
||||||
|
line = line[:mlcs] + '#' + line[mlcs+2:mlce]
|
||||||
|
else:
|
||||||
|
line = line[:mlcs] + '"""' + line[mlcs+2:mlce] + '"""' + line[mlce+2:]
|
||||||
|
else: # they are *not* together
|
||||||
|
line = line[mlce+2:mlcs]
|
||||||
|
else: # only the beginning is in this line, treat like a single-line comment for now
|
||||||
|
line = line[:mlcs]
|
||||||
|
incomment = True
|
||||||
|
elif incomment: # no mlc-starter found... are we incomment? then ignore until the end of comment
|
||||||
|
if (mlce>-1):
|
||||||
|
line = line[mlce+2:]
|
||||||
|
incomment = False
|
||||||
|
else:
|
||||||
|
line = ''
|
||||||
|
if incomment: # if we're still incomment, this whole line is comment
|
||||||
|
continue
|
||||||
|
|
||||||
|
# chop initial and trailing whitespace
|
||||||
|
line = line.strip()
|
||||||
|
|
||||||
|
# now we can actually parse the line
|
||||||
|
if (line.startswith("#define ")):
|
||||||
|
line = line[8:].strip() # peel off any additional spaces after the #define
|
||||||
|
pieces = line.split(" ", 1)
|
||||||
|
if len(pieces)<2:
|
||||||
|
continue
|
||||||
|
name, value = pieces
|
||||||
|
if "(" in name:
|
||||||
|
print >>sys.stderr,("SKIPPING: %s"%(line))
|
||||||
|
continue # skip adding "function" defines
|
||||||
|
defs[name.strip()] = value.strip()
|
||||||
|
|
||||||
|
elif (line.startswith("SFR(")):
|
||||||
|
endparen = line.find(")")
|
||||||
|
if (endparen == -1):
|
||||||
|
print >>sys.stderr,("ERROR: SFR without end parens: '%s'"%(line))
|
||||||
|
continue
|
||||||
|
line = line[4:endparen].strip()
|
||||||
|
name, value = line.split(",", 1)
|
||||||
|
defs[name.strip()] = value.strip()
|
||||||
|
elif (line.startswith("SFRX(")):
|
||||||
|
endparen = line.find(")")
|
||||||
|
if (endparen == -1):
|
||||||
|
print >>sys.stderr,("ERROR: SFRX without end parens: '%s'"%(line))
|
||||||
|
continue
|
||||||
|
line = line[5:endparen].strip()
|
||||||
|
name, value = line.split(",", 1)
|
||||||
|
defs[name.strip()] = value.strip()
|
||||||
|
elif (line.startswith("SBIT")):
|
||||||
|
endparen = line.find(")")
|
||||||
|
if (endparen == -1):
|
||||||
|
print >>sys.stderr,("ERROR: SBIT without end parens: '%s'"%(line))
|
||||||
|
continue
|
||||||
|
line = line[5:endparen].strip()
|
||||||
|
name, val1, val2 = line.split(",", 2)
|
||||||
|
defs[name.strip()] = 1 << (int(val2.strip()))
|
||||||
|
|
||||||
|
return defs
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
defs = {}
|
||||||
|
defs.update(parseLines(file('../includes/cc1110-ext.h')))
|
||||||
|
defs.update(parseLines(file('../includes/cc1111.h')))
|
||||||
|
defs.update(parseLines(file('/usr/share/sdcc/include/mcs51/cc1110.h')))
|
||||||
|
|
||||||
|
skeys = defs.keys()
|
||||||
|
skeys.sort()
|
||||||
|
out = ["%-30s = %s"%(key,defs[key]) for key in skeys]
|
||||||
|
|
||||||
|
trueout = []
|
||||||
|
for x in out:
|
||||||
|
try:
|
||||||
|
compile(x,'stdin','exec')
|
||||||
|
trueout.append(x)
|
||||||
|
print(x)
|
||||||
|
except:
|
||||||
|
sys.excepthook(*sys.exc_info())
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
#!/usr/bin/python
|
||||||
|
import sys, serial
|
||||||
|
|
||||||
|
port = "ACM0"
|
||||||
|
if len(sys.argv) > 1:
|
||||||
|
port = sys.argv.pop()
|
||||||
|
|
||||||
|
dport = "/dev/tty" + port
|
||||||
|
|
||||||
|
print "Opening serial port %s for listening..." % dport
|
||||||
|
s=serial.Serial(dport, 115200)
|
||||||
|
|
||||||
|
counter = 0
|
||||||
|
while True:
|
||||||
|
print ("%d: %s" % (counter, repr(s.read(12))))
|
||||||
|
counter += 1
|
||||||
|
#sys.stdout.write(s.read(1))
|
||||||
|
#sys.stdout.flush()
|
|
@ -0,0 +1,311 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
#
|
||||||
|
# Copyright 2012 atlas
|
||||||
|
#
|
||||||
|
# This file was adapted from a part of Project Ubertooth written by Jared Boone
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2, 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., 51 Franklin Street,
|
||||||
|
# Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import time
|
||||||
|
import numpy
|
||||||
|
import threading
|
||||||
|
import rflib
|
||||||
|
import cPickle as pickle
|
||||||
|
|
||||||
|
from PySide import QtCore, QtGui
|
||||||
|
from PySide.QtCore import Qt, QPointF, QLineF
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
APP_SPECAN = 0x43
|
||||||
|
SPECAN_QUEUE = 1
|
||||||
|
|
||||||
|
class SpecanThread(threading.Thread):
|
||||||
|
def __init__(self, data, low_frequency, high_frequency, freq_step, delay, new_frame_callback):
|
||||||
|
threading.Thread.__init__(self)
|
||||||
|
self.daemon = True
|
||||||
|
|
||||||
|
self._data = data
|
||||||
|
|
||||||
|
self._delay = delay
|
||||||
|
self._low_frequency = low_frequency
|
||||||
|
self._high_frequency = high_frequency
|
||||||
|
self._freq_step = freq_step
|
||||||
|
self._new_frame_callback = new_frame_callback
|
||||||
|
self._stop = False
|
||||||
|
self._stopped = False
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
# this is where we pull in the data from the device
|
||||||
|
#frame_source = self._device.specan(self._low_frequency, self._high_frequency)
|
||||||
|
|
||||||
|
num_chans = int((self._high_frequency - self._low_frequency) / self._freq_step)
|
||||||
|
|
||||||
|
if type(self._data) == list:
|
||||||
|
for rssi_values, timestamp in self._data:
|
||||||
|
rssi_values = [ ((ord(x)^0x80)/2)-88 for x in rssi_values[4:] ]
|
||||||
|
# since we are not accessing the dongle, we need some sort of delay
|
||||||
|
time.sleep(self._delay)
|
||||||
|
frequency_axis = numpy.linspace(self._low_frequency, self._high_frequency, num=len(rssi_values), endpoint=True)
|
||||||
|
|
||||||
|
self._new_frame_callback(numpy.copy(frequency_axis), numpy.copy(rssi_values))
|
||||||
|
if self._stop:
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
while not self._stop:
|
||||||
|
try:
|
||||||
|
rssi_values, timestamp = self._data.recv(APP_SPECAN, SPECAN_QUEUE, 10000)
|
||||||
|
rssi_values = [ ((ord(x)^0x80)/2)-88 for x in rssi_values ]
|
||||||
|
frequency_axis = numpy.linspace(self._low_frequency, self._high_frequency, num=len(rssi_values), endpoint=True)
|
||||||
|
|
||||||
|
self._new_frame_callback(numpy.copy(frequency_axis), numpy.copy(rssi_values))
|
||||||
|
except:
|
||||||
|
sys.excepthook(*sys.exc_info())
|
||||||
|
self._data._stopSpecAn()
|
||||||
|
|
||||||
|
def stop(self):
|
||||||
|
self._stop = True
|
||||||
|
self.join(3.0)
|
||||||
|
self._stopped = True
|
||||||
|
|
||||||
|
class RenderArea(QtGui.QWidget):
|
||||||
|
def __init__(self, data, low_freq=2.400e9, high_freq=2.483e9, freq_step=1e6, delay=0, parent=None):
|
||||||
|
QtGui.QWidget.__init__(self, parent)
|
||||||
|
|
||||||
|
self._graph = None
|
||||||
|
self._reticle = None
|
||||||
|
|
||||||
|
self._data = data
|
||||||
|
self._delay = delay
|
||||||
|
self._frame = None
|
||||||
|
self._persisted_frames = None
|
||||||
|
self._persisted_frames_depth = 350
|
||||||
|
self._path_max = None
|
||||||
|
|
||||||
|
self._low_frequency = low_freq #2.400e9
|
||||||
|
self._high_frequency = high_freq #2.483e9
|
||||||
|
self._frequency_step = freq_step #1e6
|
||||||
|
self._high_dbm = 0.0
|
||||||
|
self._low_dbm = -100.0
|
||||||
|
|
||||||
|
self._thread = SpecanThread(self._data,
|
||||||
|
self._low_frequency,
|
||||||
|
self._high_frequency,
|
||||||
|
self._frequency_step,
|
||||||
|
self._delay,
|
||||||
|
self._new_frame)
|
||||||
|
self._thread.start()
|
||||||
|
|
||||||
|
def stop_thread(self):
|
||||||
|
self._thread.stop()
|
||||||
|
|
||||||
|
def _new_graph(self):
|
||||||
|
self._graph = QtGui.QPixmap(self.width(), self.height())
|
||||||
|
self._graph.fill(Qt.black)
|
||||||
|
|
||||||
|
def _new_reticle(self):
|
||||||
|
self._reticle = QtGui.QPixmap(self.width(), self.height())
|
||||||
|
self._reticle.fill(Qt.transparent)
|
||||||
|
|
||||||
|
def _new_persisted_frames(self, frequency_bins):
|
||||||
|
self._persisted_frames = numpy.empty((self._persisted_frames_depth, frequency_bins))
|
||||||
|
self._persisted_frames.fill(-128 + -54)
|
||||||
|
self._persisted_frames_next_index = 0
|
||||||
|
|
||||||
|
def minimumSizeHint(self):
|
||||||
|
x_points = round((self._high_frequency - self._low_frequency) / self._frequency_step)
|
||||||
|
y_points = round(self._high_dbm - self._low_dbm)
|
||||||
|
return QtCore.QSize(x_points * 4, y_points * 1)
|
||||||
|
|
||||||
|
def _new_frame(self, frequency_axis, rssi_values):
|
||||||
|
#print repr(frequency_axis)
|
||||||
|
#print repr(rssi_values)
|
||||||
|
self._frame = (frequency_axis, rssi_values)
|
||||||
|
if self._persisted_frames is None:
|
||||||
|
self._new_persisted_frames(len(frequency_axis))
|
||||||
|
self._persisted_frames[self._persisted_frames_next_index] = rssi_values
|
||||||
|
self._persisted_frames_next_index = (self._persisted_frames_next_index + 1) % self._persisted_frames.shape[0]
|
||||||
|
self.update()
|
||||||
|
|
||||||
|
def _draw_graph(self):
|
||||||
|
if self._graph is None:
|
||||||
|
self._new_graph()
|
||||||
|
elif self._graph.size() != self.size():
|
||||||
|
self._new_graph()
|
||||||
|
|
||||||
|
painter = QtGui.QPainter(self._graph)
|
||||||
|
try:
|
||||||
|
painter.setRenderHint(QtGui.QPainter.Antialiasing)
|
||||||
|
painter.fillRect(0, 0, self._graph.width(), self._graph.height(), QtGui.QColor(0, 0, 0, 10))
|
||||||
|
|
||||||
|
if self._frame:
|
||||||
|
frequency_axis, rssi_values = self._frame
|
||||||
|
|
||||||
|
path_now = QtGui.QPainterPath()
|
||||||
|
path_max = QtGui.QPainterPath()
|
||||||
|
|
||||||
|
bins = range(len(frequency_axis))
|
||||||
|
x_axis = self._hz_to_x(frequency_axis)
|
||||||
|
y_now = self._dbm_to_y(rssi_values)
|
||||||
|
y_max = self._dbm_to_y(numpy.amax(self._persisted_frames, axis=0))
|
||||||
|
|
||||||
|
# TODO: Wrapped Numpy types with float() to support old (<1.0) PySide API in Ubuntu 10.10
|
||||||
|
path_now.moveTo(float(x_axis[0]), float(y_now[0]))
|
||||||
|
for i in bins:
|
||||||
|
path_now.lineTo(float(x_axis[i]), float(y_now[i]))
|
||||||
|
|
||||||
|
# TODO: Wrapped Numpy types with float() to support old (<1.0) PySide API in Ubuntu 10.10
|
||||||
|
path_max.moveTo(float(x_axis[0]), float(y_max[0]))
|
||||||
|
for i in bins:
|
||||||
|
path_max.lineTo(float(x_axis[i]), float(y_max[i]))
|
||||||
|
|
||||||
|
painter.setPen(Qt.white)
|
||||||
|
painter.drawPath(path_now)
|
||||||
|
self._path_max = path_max
|
||||||
|
finally:
|
||||||
|
painter.end()
|
||||||
|
|
||||||
|
def _draw_reticle(self):
|
||||||
|
if self._reticle is None or (self._reticle.size() != self.size()):
|
||||||
|
self._new_reticle()
|
||||||
|
|
||||||
|
dbm_lines = [QLineF(self._hz_to_x(self._low_frequency), self._dbm_to_y(dbm),
|
||||||
|
self._hz_to_x(self._high_frequency), self._dbm_to_y(dbm))
|
||||||
|
for dbm in numpy.arange(self._low_dbm, self._high_dbm, 20.0)]
|
||||||
|
dbm_labels = [(dbm, QPointF(self._hz_to_x(self._low_frequency) + 2, self._dbm_to_y(dbm) - 2))
|
||||||
|
for dbm in numpy.arange(self._low_dbm, self._high_dbm, 20.0)]
|
||||||
|
|
||||||
|
frequency_lines = [QLineF(self._hz_to_x(frequency), self._dbm_to_y(self._high_dbm),
|
||||||
|
self._hz_to_x(frequency), self._dbm_to_y(self._low_dbm))
|
||||||
|
for frequency in numpy.arange(self._low_frequency, self._high_frequency, self._frequency_step * 20.0)]
|
||||||
|
frequency_labels = [(frequency, QPointF(self._hz_to_x(frequency) + 2, self._dbm_to_y(self._high_dbm) + 10))
|
||||||
|
for frequency in numpy.arange(self._low_frequency, self._high_frequency, self._frequency_step * 10.0)]
|
||||||
|
|
||||||
|
painter = QtGui.QPainter(self._reticle)
|
||||||
|
try:
|
||||||
|
painter.setRenderHint(QtGui.QPainter.Antialiasing)
|
||||||
|
|
||||||
|
painter.setPen(Qt.blue)
|
||||||
|
|
||||||
|
# TODO: Removed to support old (<1.0) PySide API in Ubuntu 10.10
|
||||||
|
#painter.drawLines(dbm_lines)
|
||||||
|
for dbm_line in dbm_lines: painter.drawLine(dbm_line)
|
||||||
|
# TODO: Removed to support old (<1.0) PySide API in Ubuntu 10.10
|
||||||
|
#painter.drawLines(frequency_lines)
|
||||||
|
for frequency_line in frequency_lines: painter.drawLine(frequency_line)
|
||||||
|
|
||||||
|
painter.setPen(Qt.white)
|
||||||
|
for dbm, point in dbm_labels:
|
||||||
|
painter.drawText(point, '%+.0f' % dbm)
|
||||||
|
for frequency, point in frequency_labels:
|
||||||
|
painter.drawText(point, '%.02f' % (frequency / 1e6))
|
||||||
|
|
||||||
|
finally:
|
||||||
|
painter.end()
|
||||||
|
|
||||||
|
def paintEvent(self, event):
|
||||||
|
self._draw_graph()
|
||||||
|
self._draw_reticle()
|
||||||
|
|
||||||
|
painter = QtGui.QPainter(self)
|
||||||
|
try:
|
||||||
|
painter.setRenderHint(QtGui.QPainter.Antialiasing)
|
||||||
|
painter.setPen(QtGui.QPen())
|
||||||
|
painter.setBrush(QtGui.QBrush())
|
||||||
|
|
||||||
|
if self._graph:
|
||||||
|
painter.drawPixmap(0, 0, self._graph)
|
||||||
|
|
||||||
|
if self._path_max:
|
||||||
|
painter.setPen(Qt.green)
|
||||||
|
painter.drawPath(self._path_max)
|
||||||
|
|
||||||
|
painter.setOpacity(0.5)
|
||||||
|
if self._reticle:
|
||||||
|
painter.drawPixmap(0, 0, self._reticle)
|
||||||
|
finally:
|
||||||
|
painter.end()
|
||||||
|
|
||||||
|
def _hz_to_x(self, frequency_hz):
|
||||||
|
delta = frequency_hz - self._low_frequency
|
||||||
|
range = self._high_frequency - self._low_frequency
|
||||||
|
normalized = delta / range
|
||||||
|
#print "freq: %s \nlow: %s \nhigh: %s \ndelta: %s \nrange: %s \nnormalized: %s" % (frequency_hz, self._low_frequency, self._high_frequency, delta, range, normalized)
|
||||||
|
return normalized * self.width()
|
||||||
|
|
||||||
|
def _dbm_to_y(self, dbm):
|
||||||
|
delta = self._high_dbm - dbm
|
||||||
|
range = self._high_dbm - self._low_dbm
|
||||||
|
normalized = delta / range
|
||||||
|
return normalized * self.height()
|
||||||
|
|
||||||
|
class Window(QtGui.QWidget):
|
||||||
|
def __init__(self, data, low_freq, high_freq, spacing, delay=.01, parent=None):
|
||||||
|
QtGui.QWidget.__init__(self, parent)
|
||||||
|
|
||||||
|
self._low_freq = low_freq
|
||||||
|
self._high_freq = high_freq
|
||||||
|
self._spacing = spacing
|
||||||
|
|
||||||
|
self._data = self._open_data(data)
|
||||||
|
|
||||||
|
self.render_area = RenderArea(self._data, low_freq, high_freq, spacing, delay)
|
||||||
|
|
||||||
|
main_layout = QtGui.QGridLayout()
|
||||||
|
main_layout.setContentsMargins(0, 0, 0, 0)
|
||||||
|
main_layout.addWidget(self.render_area, 0, 0)
|
||||||
|
self.setLayout(main_layout)
|
||||||
|
|
||||||
|
self.setWindowTitle("RfCat Spectrum Analyzer (thanks Ubertooth!)")
|
||||||
|
|
||||||
|
def sizeHint(self):
|
||||||
|
return QtCore.QSize(480, 160)
|
||||||
|
|
||||||
|
def _open_data(self, data):
|
||||||
|
if type(data) == str:
|
||||||
|
if data == '-':
|
||||||
|
data = rflib.RfCat()
|
||||||
|
data._debug = 1
|
||||||
|
freq = int(self._low_freq)
|
||||||
|
spc = int(self._spacing)
|
||||||
|
numChans = int((self._high_freq-self._low_freq) / self._spacing)
|
||||||
|
data._doSpecAn(freq, spc, numChans)
|
||||||
|
else:
|
||||||
|
data = pickle.load(file(data,'rb'))
|
||||||
|
if data is None:
|
||||||
|
raise Exception('Data not found')
|
||||||
|
return data
|
||||||
|
|
||||||
|
def closeEvent(self, event):
|
||||||
|
self.render_area.stop_thread()
|
||||||
|
event.accept()
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
app = QtGui.QApplication(sys.argv)
|
||||||
|
f = sys.argv[1]
|
||||||
|
fbase = eval(sys.argv[2])
|
||||||
|
fhigh = eval(sys.argv[3])
|
||||||
|
fdelta = eval(sys.argv[4])
|
||||||
|
if len(sys.argv) > 5:
|
||||||
|
delay = eval(sys.argv[5])
|
||||||
|
else:
|
||||||
|
delay = .01
|
||||||
|
|
||||||
|
window = Window(f, fbase, fhigh, fdelta, delay)
|
||||||
|
#window = Window('../data.again', 902.0, 928.0, 3e-1)
|
||||||
|
window.show()
|
||||||
|
sys.exit(app.exec_())
|
|
@ -0,0 +1,455 @@
|
||||||
|
#!/usr/bin/env ipython
|
||||||
|
import sys
|
||||||
|
import usb
|
||||||
|
import code
|
||||||
|
import time
|
||||||
|
import struct
|
||||||
|
import threading
|
||||||
|
import re
|
||||||
|
#from chipcondefs import *
|
||||||
|
from cc1111client import *
|
||||||
|
|
||||||
|
APP_NIC = 0x42
|
||||||
|
NIC_RECV = 0x1
|
||||||
|
NIC_XMIT = 0x2
|
||||||
|
NIC_SET_ID = 0x3
|
||||||
|
NIC_RFMODE = 0x4
|
||||||
|
NIC_SET_RECV_LARGE = 0x5
|
||||||
|
NIC_SET_AES_MODE = 0x6
|
||||||
|
NIC_GET_AES_MODE = 0x7
|
||||||
|
NIC_SET_AES_IV = 0x8
|
||||||
|
NIC_SET_AES_KEY = 0x9
|
||||||
|
|
||||||
|
|
||||||
|
FHSS_SET_CHANNELS = 0x10
|
||||||
|
FHSS_NEXT_CHANNEL = 0x11
|
||||||
|
FHSS_CHANGE_CHANNEL = 0x12
|
||||||
|
FHSS_SET_MAC_THRESHOLD = 0x13
|
||||||
|
FHSS_GET_MAC_THRESHOLD = 0x14
|
||||||
|
FHSS_SET_MAC_DATA = 0x15
|
||||||
|
FHSS_GET_MAC_DATA = 0x16
|
||||||
|
FHSS_XMIT = 0x17
|
||||||
|
FHSS_GET_CHANNELS = 0x18
|
||||||
|
|
||||||
|
FHSS_SET_STATE = 0x20
|
||||||
|
FHSS_GET_STATE = 0x21
|
||||||
|
FHSS_START_SYNC = 0x22
|
||||||
|
FHSS_START_HOPPING = 0x23
|
||||||
|
FHSS_STOP_HOPPING = 0x24
|
||||||
|
|
||||||
|
FHSS_STATE_NONHOPPING = 0
|
||||||
|
FHSS_STATE_DISCOVERY = 1
|
||||||
|
FHSS_STATE_SYNCHING = 2
|
||||||
|
FHSS_LAST_NONHOPPING_STATE = FHSS_STATE_SYNCHING
|
||||||
|
|
||||||
|
FHSS_STATE_SYNCHED = 3
|
||||||
|
FHSS_STATE_SYNC_MASTER = 4
|
||||||
|
FHSS_STATE_SYNCINGMASTER = 5
|
||||||
|
FHSS_LAST_STATE = 5 # used for testing
|
||||||
|
|
||||||
|
|
||||||
|
FHSS_STATES = {}
|
||||||
|
for key,val in globals().items():
|
||||||
|
if key.startswith("FHSS_STATE_"):
|
||||||
|
FHSS_STATES[key] = val
|
||||||
|
FHSS_STATES[val] = key
|
||||||
|
|
||||||
|
|
||||||
|
T2SETTINGS = {}
|
||||||
|
T2SETTINGS_24MHz = {
|
||||||
|
100: (4, 147, 3),
|
||||||
|
150: (5, 110, 3),
|
||||||
|
200: (5, 146, 3),
|
||||||
|
250: (5, 183, 3),
|
||||||
|
}
|
||||||
|
T2SETTINGS_26MHz = {
|
||||||
|
100: (4, 158, 3),
|
||||||
|
150: (5, 119, 3),
|
||||||
|
200: (5, 158, 3),
|
||||||
|
250: (5, 198, 3),
|
||||||
|
}
|
||||||
|
|
||||||
|
TIP = (64,128,256,1024)
|
||||||
|
|
||||||
|
def calculateT2(ms, mhz=24):
|
||||||
|
TICKSPD = [(mhz*1000000/pow(2,x)) for x in range(8)]
|
||||||
|
|
||||||
|
ms = 1.0*ms/1000
|
||||||
|
candidates = []
|
||||||
|
for tickidx in xrange(8):
|
||||||
|
for tipidx in range(4):
|
||||||
|
for PR in xrange(256):
|
||||||
|
T = 1.0 * PR * TIP[tipidx] / TICKSPD[tickidx]
|
||||||
|
if abs(T-ms) < .010:
|
||||||
|
candidates.append((T, tickidx, tipidx, PR))
|
||||||
|
diff = 1024
|
||||||
|
best = None
|
||||||
|
for c in candidates:
|
||||||
|
if abs(c[0] - ms) < diff:
|
||||||
|
best = c
|
||||||
|
diff = abs(c[0] - ms)
|
||||||
|
return best
|
||||||
|
#return ms, candidates, best
|
||||||
|
|
||||||
|
def invertBits(data):
|
||||||
|
output = []
|
||||||
|
ldata = len(data)
|
||||||
|
off = 0
|
||||||
|
|
||||||
|
if ldata&1:
|
||||||
|
output.append( chr( ord( data[0] ) ^ 0xff) )
|
||||||
|
off = 1
|
||||||
|
|
||||||
|
if ldata&2:
|
||||||
|
output.append( struct.pack( "<H", struct.unpack( "<H", data[off:off+2] )[0] ^ 0xffff) )
|
||||||
|
off += 2
|
||||||
|
|
||||||
|
#method 1
|
||||||
|
#for idx in xrange( off, ldata, 4):
|
||||||
|
# output.append( struct.pack( "<I", struct.unpack( "<I", data[idx:idx+4] )[0] & 0xffff) )
|
||||||
|
|
||||||
|
#method2
|
||||||
|
count = ldata / 4
|
||||||
|
#print ldata, count
|
||||||
|
numlist = struct.unpack( "<%dI" % count, data[off:] )
|
||||||
|
modlist = [ struct.pack("<L", (x^0xffffffff) ) for x in numlist ]
|
||||||
|
output.extend(modlist)
|
||||||
|
|
||||||
|
return ''.join(output)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
class FHSSNIC(USBDongle):
|
||||||
|
def __init__(self, idx=0, debug=False, copyDongle=None):
|
||||||
|
USBDongle.__init__(self, idx, debug, copyDongle)
|
||||||
|
|
||||||
|
def setRfMode(self, rfmode, parms=''):
|
||||||
|
r = self.send(APP_NIC, NIC_RFMODE, "%c"%rfmode + parms)
|
||||||
|
|
||||||
|
def setAESmode(self, aesmode=AES_CRYPTO_DEFAULT):
|
||||||
|
'''
|
||||||
|
set AES crypto co-processor mode.
|
||||||
|
crypto operations on inbound and outbound RF packets are independently supported
|
||||||
|
as is the type of operation. normally this would be ENCRYPT on outbound and DECRYPT
|
||||||
|
on inbound.
|
||||||
|
aesmode is a bitfield. the upper half mirrors the CC1111 standard modes (CBC, ECB etc.),
|
||||||
|
and the lower half flags whether to encrypt or not on inbound/outbound as well as which
|
||||||
|
operation to perform:
|
||||||
|
|
||||||
|
aesmode[7:4] ENCCS_MODE...
|
||||||
|
aesmode[3] OUTBOUND 0 == OFF, 1 == ON
|
||||||
|
aesmode[2] OUTBOUND 0 == Decrypt, 1 == Encrypt
|
||||||
|
aesmode[1] INBOUND 0 == OFF, 1 == ON
|
||||||
|
aesmode[0] INBOUND 0 == Decrypt, 1 == Encrypt
|
||||||
|
|
||||||
|
the following are defined in chipcondefs.
|
||||||
|
|
||||||
|
valid CC1111 modes are:
|
||||||
|
|
||||||
|
ENCCS_MODE_CBC
|
||||||
|
ENCCS_MODE_CBCMAC
|
||||||
|
ENCCS_MODE_CFB
|
||||||
|
ENCCS_MODE_CTR
|
||||||
|
ENCCS_MODE_ECB
|
||||||
|
ENCCS_MODE_OFB
|
||||||
|
|
||||||
|
valid AES operational modes are:
|
||||||
|
|
||||||
|
AES_CRYPTO_IN_ON
|
||||||
|
AES_CRYPTO_IN_OFF
|
||||||
|
AES_CRYPTO_IN_ENCRYPT
|
||||||
|
AES_CRYPTO_IN_DECRYPT
|
||||||
|
AES_CRYPTO_OUT_ON
|
||||||
|
AES_CRYPTO_OUT_OFF
|
||||||
|
AES_CRYPTO_OUT_ENCRYPT
|
||||||
|
AES_CRYPTO_OUT_DECRYPT
|
||||||
|
|
||||||
|
aesmode is made up of the appropriate combination of the above.
|
||||||
|
default is CBC mode, crypto enabled IN and OUT:
|
||||||
|
|
||||||
|
(ENCCS_MODE_CBC | AES_CRYPTO_OUT_ON | AES_CRYPTO_OUT_ENCRYPT | AES_CRYPTO_IN_ON | AES_CRYPTO_IN_DECRYPT)
|
||||||
|
|
||||||
|
'''
|
||||||
|
return self.send(APP_NIC, NIC_SET_AES_MODE, "%c"%aesmode)
|
||||||
|
|
||||||
|
def getAESmode(self):
|
||||||
|
'''
|
||||||
|
get the currently set AES co-processor mode
|
||||||
|
'''
|
||||||
|
return self.send(APP_NIC, NIC_GET_AES_MODE, "")
|
||||||
|
|
||||||
|
def setAESiv(self, iv= '\0'*16):
|
||||||
|
'''
|
||||||
|
set the AES IV. this will persist until the next reboot, but it should be noted that some modes
|
||||||
|
update the IV automatically with each operation, so care must be taken with the higher level
|
||||||
|
protocol to ensure lost packets etc. do not cause synchronisation problems. IV must be 128 bits.
|
||||||
|
'''
|
||||||
|
return self.send(APP_NIC, NIC_SET_AES_IV, iv)
|
||||||
|
|
||||||
|
def setAESkey(self, key= '\0'*16):
|
||||||
|
'''
|
||||||
|
set the AES key. this will persist until the next reboot. key must be 128 bits.
|
||||||
|
'''
|
||||||
|
return self.send(APP_NIC, NIC_SET_AES_KEY, key)
|
||||||
|
|
||||||
|
# set repeat & offset to optionally repeat tx of a section of the data block. repeat of 65535 means 'forever'
|
||||||
|
def RFxmit(self, data, repeat=0, offset=0):
|
||||||
|
# calculate wait time
|
||||||
|
waitlen = len(data)
|
||||||
|
waitlen += repeat * (len(data) - offset)
|
||||||
|
wait = USB_TX_WAIT * ((waitlen / RF_MAX_TX_BLOCK) + 1)
|
||||||
|
self.send(APP_NIC, NIC_XMIT, "%s" % struct.pack("<HHH",len(data),repeat,offset)+data, wait=wait)
|
||||||
|
|
||||||
|
# set blocksize to larger than 255 to receive large blocks or 0 to revert to normal
|
||||||
|
def RFrecv(self, timeout=USB_RX_WAIT, blocksize=None):
|
||||||
|
if not blocksize == None:
|
||||||
|
if blocksize > EP5OUT_BUFFER_SIZE:
|
||||||
|
raise(Exception("Blocksize too large. Maximum %d") % EP5OUT_BUFFER_SIZE)
|
||||||
|
self.send(APP_NIC, NIC_SET_RECV_LARGE, "%s" % struct.pack("<H",blocksize))
|
||||||
|
return self.recv(APP_NIC, NIC_RECV, timeout)
|
||||||
|
|
||||||
|
def RFlisten(self):
|
||||||
|
''' just sit and dump packets as they come in
|
||||||
|
kinda like discover() but without changing any of the communications settings '''
|
||||||
|
while not keystop():
|
||||||
|
|
||||||
|
try:
|
||||||
|
y, t = self.RFrecv()
|
||||||
|
print "(%5.3f) Received: %s" % (t, y.encode('hex'))
|
||||||
|
|
||||||
|
except ChipconUsbTimeoutException:
|
||||||
|
pass
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
print "Please press <enter> to stop"
|
||||||
|
|
||||||
|
sys.stdin.read(1)
|
||||||
|
|
||||||
|
def RFcapture(self):
|
||||||
|
''' dump packets as they come in, but return a list of packets when you exit capture mode.
|
||||||
|
kinda like discover() but without changing any of the communications settings '''
|
||||||
|
capture = []
|
||||||
|
while not keystop():
|
||||||
|
|
||||||
|
try:
|
||||||
|
y, t = self.RFrecv()
|
||||||
|
print "(%5.3f) Received: %s" % (t, y.encode('hex'))
|
||||||
|
capture.append((y,t))
|
||||||
|
|
||||||
|
except ChipconUsbTimeoutException:
|
||||||
|
pass
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
print "Please press <enter> to stop"
|
||||||
|
|
||||||
|
sys.stdin.read(1)
|
||||||
|
return capture
|
||||||
|
|
||||||
|
def FHSSxmit(self, data):
|
||||||
|
self.send(APP_NIC, FHSS_XMIT, "%c%s" % (len(data)+1, data))
|
||||||
|
|
||||||
|
def changeChannel(self, chan):
|
||||||
|
return self.send(APP_NIC, FHSS_CHANGE_CHANNEL, "%c" % (chan))
|
||||||
|
|
||||||
|
def getChannels(self, channels=[]):
|
||||||
|
return self.send(APP_NIC, FHSS_GET_CHANNELS, '')
|
||||||
|
|
||||||
|
def setChannels(self, channels=[]):
|
||||||
|
chans = ''.join(["%c" % chan for chan in channels])
|
||||||
|
length = struct.pack("<H", len(chans))
|
||||||
|
|
||||||
|
return self.send(APP_NIC, FHSS_SET_CHANNELS, length + chans)
|
||||||
|
|
||||||
|
def nextChannel(self):
|
||||||
|
return self.send(APP_NIC, FHSS_NEXT_CHANNEL, '' )
|
||||||
|
|
||||||
|
def startHopping(self):
|
||||||
|
return self.send(APP_NIC, FHSS_START_HOPPING, '')
|
||||||
|
|
||||||
|
def stopHopping(self):
|
||||||
|
return self.send(APP_NIC, FHSS_STOP_HOPPING, '')
|
||||||
|
|
||||||
|
def setMACperiod(self, ms, mhz=24):
|
||||||
|
val = calculateT2(ms, mhz)
|
||||||
|
T, tickidx, tipidx, PR = val
|
||||||
|
print "Setting MAC period to %f secs (%x %x %x)" % (val)
|
||||||
|
t2ctl = (ord(self.peek(X_T2CTL)) & 0xfc) | (tipidx)
|
||||||
|
clkcon = (ord(self.peek(X_CLKCON)) & 0xc7) | (tickidx<<3)
|
||||||
|
|
||||||
|
self.poke(X_T2PR, chr(PR))
|
||||||
|
self.poke(X_T2CTL, chr(t2ctl))
|
||||||
|
self.poke(X_CLKCON, chr(clkcon))
|
||||||
|
|
||||||
|
def setMACdata(self, data):
|
||||||
|
datastr = ''.join([chr(d) for x in data])
|
||||||
|
return self.send(APP_NIC, FHSS_SET_MAC_DATA, datastr)
|
||||||
|
|
||||||
|
def getMACdata(self):
|
||||||
|
datastr, timestamp = self.send(APP_NIC, FHSS_GET_MAC_DATA, '')
|
||||||
|
print (repr(datastr))
|
||||||
|
data = struct.unpack("<BIHHHHHHBBH", datastr)
|
||||||
|
return data
|
||||||
|
|
||||||
|
def reprMACdata(self):
|
||||||
|
data = self.getMACdata()
|
||||||
|
return """\
|
||||||
|
u8 mac_state %x
|
||||||
|
u32 MAC_threshold %x
|
||||||
|
u16 NumChannels %x
|
||||||
|
u16 NumChannelHops %x
|
||||||
|
u16 curChanIdx %x
|
||||||
|
u16 tLastStateChange %x
|
||||||
|
u16 tLastHop %x
|
||||||
|
u16 desperatelySeeking %x
|
||||||
|
u8 txMsgIdx %x
|
||||||
|
u8 txMsgIdxDone %x
|
||||||
|
u16 synched_chans %x
|
||||||
|
|
||||||
|
""" % data
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
u8 mac_state;
|
||||||
|
// MAC parameters (FIXME: make this all cc1111fhssmac.c/h?)
|
||||||
|
u32 g_MAC_threshold; // when the T2 clock as overflowed this many times, change channel
|
||||||
|
u16 g_NumChannels; // in case of multiple paths through the available channels
|
||||||
|
u16 g_NumChannelHops; // total number of channels in pattern (>= g_MaxChannels)
|
||||||
|
u16 g_curChanIdx; // indicates current channel index of the hopping pattern
|
||||||
|
u16 g_tLastStateChange;
|
||||||
|
u16 g_tLastHop;
|
||||||
|
u16 g_desperatelySeeking;
|
||||||
|
u8 g_txMsgIdx;
|
||||||
|
"""
|
||||||
|
|
||||||
|
def getMACthreshold(self):
|
||||||
|
return self.send(APP_NIC, FHSS_SET_MAC_THRESHOLD, struct.pack("<I",value))
|
||||||
|
|
||||||
|
def setMACthreshold(self, value):
|
||||||
|
return self.send(APP_NIC, FHSS_SET_MAC_THRESHOLD, struct.pack("<I",value))
|
||||||
|
|
||||||
|
def setFHSSstate(self, state):
|
||||||
|
return self.send(APP_NIC, FHSS_SET_STATE, struct.pack("<I",state))
|
||||||
|
|
||||||
|
def getFHSSstate(self):
|
||||||
|
state = self.send(APP_NIC, FHSS_GET_STATE, '')
|
||||||
|
#print repr(state)
|
||||||
|
state = ord(state[0])
|
||||||
|
return FHSS_STATES[state], state
|
||||||
|
|
||||||
|
def mac_SyncCell(self, CellID=0x0000):
|
||||||
|
return self.send(APP_NIC, FHSS_START_SYNC, struct.pack("<H",CellID))
|
||||||
|
|
||||||
|
def setPktAddr(self, addr):
|
||||||
|
return self.poke(ADDR, chr(addr))
|
||||||
|
|
||||||
|
def getPktAddr(self):
|
||||||
|
return self.peek(ADDR)
|
||||||
|
|
||||||
|
def discover(self, lowball=1, debug=None, length=30, IdentSyncWord=False, SyncWordMatchList=None, Search=None, RegExpSearch=None):
|
||||||
|
'''
|
||||||
|
discover() sets lowball mode to the mode requested (length too), and begins to dump packets to the screen.
|
||||||
|
press <enter> to quit, and your radio config will be set back to its original configuration.
|
||||||
|
|
||||||
|
lowball - lowball level of choosing (see help on lowball)
|
||||||
|
debug - sets _debug to this setting if not None.
|
||||||
|
length - arbitrary length of bytes we want to see per pseudopacket. (should be enough to identify interesting packets, but not too long)
|
||||||
|
IdentSyncWord - look for preamble in each packet and determine possible sync-words in use
|
||||||
|
SyncWordMatchList - attempt to find *these* sync words (provide a list)
|
||||||
|
Search - byte string to search through each received packet for (real bytes, not hex repr)
|
||||||
|
RegExpSearch - regular expression to search through received bytes (not the hex repr that is printed)
|
||||||
|
|
||||||
|
'''
|
||||||
|
oldebug = self._debug
|
||||||
|
if IdentSyncWord and lowball <= 1:
|
||||||
|
print "Entering Discover mode and searching for possible SyncWords..."
|
||||||
|
if SyncWordMatchList is not None:
|
||||||
|
print " seeking one of: %s" % repr([hex(x) for x in SyncWordMatchList])
|
||||||
|
|
||||||
|
else:
|
||||||
|
if IdentSyncWord and lowball > 1:
|
||||||
|
print "-- lowball too high -- ignoring request to IdentSyncWord"
|
||||||
|
IdentSyncWord = False
|
||||||
|
|
||||||
|
print "Entering Discover mode..."
|
||||||
|
|
||||||
|
self.lowball(level=lowball, length=length)
|
||||||
|
if debug is not None:
|
||||||
|
self._debug = debug
|
||||||
|
|
||||||
|
if Search is not None:
|
||||||
|
print "Search:",repr(Search)
|
||||||
|
|
||||||
|
if RegExpSearch is not None:
|
||||||
|
print "RegExpSearch:",repr(RegExpSearch)
|
||||||
|
|
||||||
|
while not keystop():
|
||||||
|
|
||||||
|
try:
|
||||||
|
y, t = self.RFrecv()
|
||||||
|
yhex = y.encode('hex')
|
||||||
|
|
||||||
|
print "(%5.3f) Received: %s" % (t, yhex)
|
||||||
|
if RegExpSearch is not None:
|
||||||
|
ynext = y
|
||||||
|
for loop in range(8):
|
||||||
|
if (re.Search(RegExpSearch, ynext) is not None):
|
||||||
|
print " REG EXP SEARCH SUCCESS:",RegExpSearch
|
||||||
|
ynext = bits.shiftString(ynext, 1)
|
||||||
|
|
||||||
|
if Search is not None:
|
||||||
|
ynext = y
|
||||||
|
for loop in range(8):
|
||||||
|
if (Search in ynext):
|
||||||
|
print " SEARCH SUCCESS:",Search
|
||||||
|
ynext = bits.shiftString(ynext, 1)
|
||||||
|
|
||||||
|
if IdentSyncWord:
|
||||||
|
if lowball == 1:
|
||||||
|
y = '\xaa\xaa' + y
|
||||||
|
|
||||||
|
poss = bits.findDword(y)
|
||||||
|
if len(poss):
|
||||||
|
print " possible Sync Dwords: %s" % repr([hex(x) for x in poss])
|
||||||
|
|
||||||
|
if SyncWordMatchList is not None:
|
||||||
|
for x in poss:
|
||||||
|
if x in SyncWordMatchList:
|
||||||
|
print "MATCH WITH KNOWN SYNC WORD:" + hex(x)
|
||||||
|
|
||||||
|
except ChipconUsbTimeoutException:
|
||||||
|
pass
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
print "Please press <enter> to stop"
|
||||||
|
|
||||||
|
sys.stdin.read(1)
|
||||||
|
self._debug = oldebug
|
||||||
|
self.lowballRestore()
|
||||||
|
print "Exiting Discover mode..."
|
||||||
|
|
||||||
|
def testTX(self, data="XYZABCDEFGHIJKL"):
|
||||||
|
while (sys.stdin not in select.select([sys.stdin],[],[],0)[0]):
|
||||||
|
time.sleep(.4)
|
||||||
|
print "transmitting %s" % repr(data)
|
||||||
|
self.RFxmit(data)
|
||||||
|
sys.stdin.read(1)
|
||||||
|
|
||||||
|
|
||||||
|
def unittest(dongle):
|
||||||
|
import cc1111client
|
||||||
|
cc1111client.unittest(dongle)
|
||||||
|
|
||||||
|
print "\nTesting FHSS State set/get"
|
||||||
|
fhssstate = dongle.getFHSSstate()
|
||||||
|
print repr(fhssstate)
|
||||||
|
for stateidx in range(FHSS_LAST_STATE+1):
|
||||||
|
print repr(dongle.setFHSSstate(stateidx))
|
||||||
|
print repr(dongle.getFHSSstate())
|
||||||
|
|
||||||
|
print repr(dongle.setFHSSstate(fhssstate[1] ))
|
||||||
|
print repr(dongle.getFHSSstate())
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
idx = 0
|
||||||
|
if len(sys.argv) > 1:
|
||||||
|
idx = int(sys.argv.pop())
|
||||||
|
d = FHSSNIC(idx=idx)
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,29 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
import sys
|
||||||
|
from rflib import *
|
||||||
|
import rflib.chipcon_nic as rfnic
|
||||||
|
import atexit
|
||||||
|
from libtoorchat import *
|
||||||
|
|
||||||
|
def banner():
|
||||||
|
print "******** ToorChat [v 0.1] ********"
|
||||||
|
|
||||||
|
def main():
|
||||||
|
banner()
|
||||||
|
badge = RfCat(idx=0)
|
||||||
|
badge.setModeRX()
|
||||||
|
protocol = ToorChatProtocol(badge)
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
msg, timestamp = badge.RFrecv()
|
||||||
|
print "enter a message"
|
||||||
|
# send = input("Enter a message")
|
||||||
|
# protocol.send_message(send)
|
||||||
|
except ChipconUsbTimeoutException:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
|
@ -0,0 +1,286 @@
|
||||||
|
|
||||||
|
import struct
|
||||||
|
from StringIO import StringIO
|
||||||
|
|
||||||
|
import vstruct.primitives as vs_prims
|
||||||
|
|
||||||
|
def isVstructType(x):
|
||||||
|
return isinstance(x, vs_prims.v_base)
|
||||||
|
|
||||||
|
class VStruct(vs_prims.v_base):
|
||||||
|
|
||||||
|
def __init__(self, bigend=False):
|
||||||
|
# A tiny bit of evil...
|
||||||
|
object.__setattr__(self, "_vs_values", {})
|
||||||
|
vs_prims.v_base.__init__(self)
|
||||||
|
self._vs_name = self.__class__.__name__
|
||||||
|
self._vs_fields = []
|
||||||
|
self._vs_field_align = False # To toggle visual studio style packing
|
||||||
|
self._vs_padnum = 0
|
||||||
|
self._vs_fmtbase = '<'
|
||||||
|
if bigend:
|
||||||
|
self._vs_fmtbase = '>'
|
||||||
|
|
||||||
|
def vsGetClassPath(self):
|
||||||
|
'''
|
||||||
|
Return the entire class name (including module path).
|
||||||
|
'''
|
||||||
|
return '%s.%s' % (self.__module__, self._vs_name)
|
||||||
|
|
||||||
|
def vsParse(self, bytes, offset=0):
|
||||||
|
"""
|
||||||
|
For all the primitives contained within, allow them
|
||||||
|
an opportunity to parse the given data and return the
|
||||||
|
total offset...
|
||||||
|
"""
|
||||||
|
plist = self.vsGetPrims()
|
||||||
|
fmt = self.vsGetFormat()
|
||||||
|
size = struct.calcsize(fmt)
|
||||||
|
vals = struct.unpack(fmt, bytes[offset:offset+size])
|
||||||
|
for i in range(len(plist)):
|
||||||
|
plist[i].vsSetParsedValue(vals[i])
|
||||||
|
|
||||||
|
def vsEmit(self):
|
||||||
|
"""
|
||||||
|
Get back the byte sequence associated with this structure.
|
||||||
|
"""
|
||||||
|
fmt = self.vsGetFormat()
|
||||||
|
r = []
|
||||||
|
for p in self.vsGetPrims():
|
||||||
|
r.append(p.vsGetFmtValue())
|
||||||
|
return struct.pack(fmt, *r)
|
||||||
|
|
||||||
|
def vsGetFormat(self):
|
||||||
|
"""
|
||||||
|
Return the format specifier which would then be used
|
||||||
|
"""
|
||||||
|
# Unpack everything little endian, let vsParseValue deal...
|
||||||
|
ret = self._vs_fmtbase
|
||||||
|
for p in self.vsGetPrims():
|
||||||
|
ret += p.vsGetFormat()
|
||||||
|
return ret
|
||||||
|
|
||||||
|
def vsIsPrim(self):
|
||||||
|
return False
|
||||||
|
|
||||||
|
def vsGetFields(self):
|
||||||
|
ret = []
|
||||||
|
for fname in self._vs_fields:
|
||||||
|
fobj = self._vs_values.get(fname)
|
||||||
|
ret.append((fname,fobj))
|
||||||
|
return ret
|
||||||
|
|
||||||
|
def vsGetField(self, name):
|
||||||
|
x = self._vs_values.get(name)
|
||||||
|
if x == None:
|
||||||
|
raise Exception("Invalid field: %s" % name)
|
||||||
|
return x
|
||||||
|
|
||||||
|
def vsHasField(self, name):
|
||||||
|
return self._vs_values.get(name) != None
|
||||||
|
|
||||||
|
def vsSetField(self, name, value):
|
||||||
|
if isVstructType(value):
|
||||||
|
self._vs_values[name] = value
|
||||||
|
return
|
||||||
|
x = self._vs_values.get(name)
|
||||||
|
return x.vsSetValue(value)
|
||||||
|
|
||||||
|
# FIXME implement more arithmetic for structs...
|
||||||
|
def __ixor__(self, other):
|
||||||
|
for name,value in other._vs_values.items():
|
||||||
|
self._vs_values[name] ^= value
|
||||||
|
return self
|
||||||
|
|
||||||
|
def vsAddField(self, name, value):
|
||||||
|
if not isVstructType(value):
|
||||||
|
raise Exception("Added fields MUST be vstruct types!")
|
||||||
|
|
||||||
|
# Do optional field alignment...
|
||||||
|
if self._vs_field_align:
|
||||||
|
|
||||||
|
# If it's a primitive, all is well, if not, pad to size of
|
||||||
|
# the first element of the VStruct/VArray...
|
||||||
|
if value.vsIsPrim():
|
||||||
|
align = len(value)
|
||||||
|
else:
|
||||||
|
fname = value._vs_fields[0]
|
||||||
|
align = len(value._vs_values.get(fname))
|
||||||
|
|
||||||
|
delta = len(self) % align
|
||||||
|
if delta != 0:
|
||||||
|
print "PADDING %s by %d" % (name,align-delta)
|
||||||
|
pname = "_pad%d" % self._vs_padnum
|
||||||
|
self._vs_padnum += 1
|
||||||
|
self._vs_fields.append(pname)
|
||||||
|
self._vs_values[pname] = vs_prims.v_bytes(align-delta)
|
||||||
|
|
||||||
|
self._vs_fields.append(name)
|
||||||
|
self._vs_values[name] = value
|
||||||
|
|
||||||
|
def vsGetPrims(self):
|
||||||
|
"""
|
||||||
|
return an order'd list of the primitive fields in this
|
||||||
|
structure definition. This is recursive and will return
|
||||||
|
the sub fields of all nested structures.
|
||||||
|
"""
|
||||||
|
ret = []
|
||||||
|
for name, field in self.vsGetFields():
|
||||||
|
if field.vsIsPrim():
|
||||||
|
ret.append(field)
|
||||||
|
else:
|
||||||
|
ret.extend(field.vsGetPrims())
|
||||||
|
|
||||||
|
return ret
|
||||||
|
|
||||||
|
def vsGetTypeName(self):
|
||||||
|
return self._vs_name
|
||||||
|
|
||||||
|
def vsGetOffset(self, name):
|
||||||
|
"""
|
||||||
|
Return the offset of a member.
|
||||||
|
"""
|
||||||
|
offset = 0
|
||||||
|
for fname in self._vs_fields:
|
||||||
|
if name == fname:
|
||||||
|
return offset
|
||||||
|
x = self._vs_values.get(fname)
|
||||||
|
offset += len(x)
|
||||||
|
raise Exception("Invalid Field Specified!")
|
||||||
|
|
||||||
|
def vsGetPrintInfo(self, offset=0, indent=0, top=True):
|
||||||
|
ret = []
|
||||||
|
if top:
|
||||||
|
ret.append((offset, indent, self._vs_name, self))
|
||||||
|
indent += 1
|
||||||
|
for fname in self._vs_fields:
|
||||||
|
x = self._vs_values.get(fname)
|
||||||
|
off = offset + self.vsGetOffset(fname)
|
||||||
|
if isinstance(x, VStruct):
|
||||||
|
ret.append((off, indent, fname, x))
|
||||||
|
ret.extend(x.vsGetPrintInfo(offset=off, indent=indent, top=False))
|
||||||
|
else:
|
||||||
|
ret.append((off, indent, fname, x))
|
||||||
|
return ret
|
||||||
|
|
||||||
|
def __len__(self):
|
||||||
|
fmt = self.vsGetFormat()
|
||||||
|
return struct.calcsize(fmt)
|
||||||
|
|
||||||
|
def __getattr__(self, name):
|
||||||
|
# Gotta do this for pickle issues...
|
||||||
|
vsvals = self.__dict__.get("_vs_values")
|
||||||
|
if vsvals == None:
|
||||||
|
vsvals = {}
|
||||||
|
self.__dict__["_vs_values"] = vsvals
|
||||||
|
r = vsvals.get(name)
|
||||||
|
if r is None:
|
||||||
|
raise AttributeError(name)
|
||||||
|
if isinstance(r, vs_prims.v_prim):
|
||||||
|
return r.vsGetValue()
|
||||||
|
return r
|
||||||
|
|
||||||
|
def __setattr__(self, name, value):
|
||||||
|
# If we have this field, asign to it
|
||||||
|
x = self._vs_values.get(name, None)
|
||||||
|
if x != None:
|
||||||
|
return self.vsSetField(name, value)
|
||||||
|
|
||||||
|
# If it's a vstruct type, create a new field
|
||||||
|
if isVstructType(value):
|
||||||
|
return self.vsAddField(name, value)
|
||||||
|
|
||||||
|
# Fail over to standard object attribute behavior
|
||||||
|
return object.__setattr__(self, name, value)
|
||||||
|
|
||||||
|
def __iter__(self):
|
||||||
|
# Our iteration returns name,field pairs
|
||||||
|
ret = []
|
||||||
|
for name in self._vs_fields:
|
||||||
|
ret.append((name, self._vs_values.get(name)))
|
||||||
|
return iter(ret)
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return self._vs_name
|
||||||
|
|
||||||
|
def tree(self, va=0, reprmax=None):
|
||||||
|
ret = ""
|
||||||
|
for off, indent, name, field in self.vsGetPrintInfo():
|
||||||
|
rstr = field.vsGetTypeName()
|
||||||
|
if isinstance(field, vs_prims.v_number):
|
||||||
|
val = field.vsGetValue()
|
||||||
|
rstr = '0x%.8x (%d)' % (val,val)
|
||||||
|
elif isinstance(field, vs_prims.v_prim):
|
||||||
|
rstr = repr(field)
|
||||||
|
if reprmax != None and len(rstr) > reprmax:
|
||||||
|
rstr = rstr[:reprmax] + '...'
|
||||||
|
ret += "%.8x (%.2d)%s %s: %s\n" % (va+off, len(field), " "*(indent*2),name,rstr)
|
||||||
|
return ret
|
||||||
|
|
||||||
|
class VArray(VStruct):
|
||||||
|
|
||||||
|
def __init__(self, elems=()):
|
||||||
|
VStruct.__init__(self)
|
||||||
|
for e in elems:
|
||||||
|
self.vsAddElement(e)
|
||||||
|
|
||||||
|
def vsAddElement(self, elem):
|
||||||
|
"""
|
||||||
|
Used to add elements to an array
|
||||||
|
"""
|
||||||
|
idx = len(self._vs_fields)
|
||||||
|
self.vsAddField("%d" % idx, elem)
|
||||||
|
|
||||||
|
def __getitem__(self, index):
|
||||||
|
return self.vsGetField("%d" % index)
|
||||||
|
|
||||||
|
#FIXME slice asignment
|
||||||
|
|
||||||
|
def resolve(impmod, nameparts):
|
||||||
|
"""
|
||||||
|
Resolve the given (potentially nested) object
|
||||||
|
from within a module.
|
||||||
|
"""
|
||||||
|
if not nameparts:
|
||||||
|
return None
|
||||||
|
|
||||||
|
m = impmod
|
||||||
|
for nname in nameparts:
|
||||||
|
m = getattr(m, nname, None)
|
||||||
|
if m == None:
|
||||||
|
break
|
||||||
|
|
||||||
|
return m
|
||||||
|
|
||||||
|
# NOTE: Gotta import this *after* VStruct/VSArray defined
|
||||||
|
import vstruct.defs as vs_defs
|
||||||
|
|
||||||
|
def getStructure(sname):
|
||||||
|
"""
|
||||||
|
Return an instance of the specified structure. The
|
||||||
|
structure name may be a definition that was added with
|
||||||
|
addStructure() or a python path (ie. win32.TEB) of a
|
||||||
|
definition from within vstruct.defs.
|
||||||
|
"""
|
||||||
|
x = resolve(vs_defs, sname.split("."))
|
||||||
|
if x != None:
|
||||||
|
return x()
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
|
def getModuleNames():
|
||||||
|
return [x for x in dir(vs_defs) if not x.startswith("__")]
|
||||||
|
|
||||||
|
def getStructNames(modname):
|
||||||
|
ret = []
|
||||||
|
mod = resolve(vs_defs, modname)
|
||||||
|
if mod == None:
|
||||||
|
return ret
|
||||||
|
|
||||||
|
for n in dir(mod):
|
||||||
|
x = getattr(mod, n)
|
||||||
|
if issubclass(x, VStruct):
|
||||||
|
ret.append(n)
|
||||||
|
|
||||||
|
return ret
|
||||||
|
|
|
@ -0,0 +1,249 @@
|
||||||
|
'''
|
||||||
|
|
||||||
|
VStruct builder! Used to serialize structure definitions etc...
|
||||||
|
|
||||||
|
'''
|
||||||
|
|
||||||
|
import types
|
||||||
|
import inspect
|
||||||
|
import vstruct
|
||||||
|
import vstruct.primitives as vs_prim
|
||||||
|
|
||||||
|
prim_types = [ None,
|
||||||
|
vs_prim.v_uint8,
|
||||||
|
vs_prim.v_uint16,
|
||||||
|
None,
|
||||||
|
vs_prim.v_uint32,
|
||||||
|
None, None, None,
|
||||||
|
vs_prim.v_uint64
|
||||||
|
]
|
||||||
|
|
||||||
|
# VStruct Field Flags
|
||||||
|
VSFF_ARRAY = 1
|
||||||
|
VSFF_POINTER = 2
|
||||||
|
|
||||||
|
class VStructConstructor:
|
||||||
|
def __init__(self, builder, vsname):
|
||||||
|
self.builder = builder
|
||||||
|
self.vsname = vsname
|
||||||
|
|
||||||
|
def __call__(self, *args, **kwargs):
|
||||||
|
return self.builder.buildVStruct(self.vsname)
|
||||||
|
|
||||||
|
class VStructBuilder:
|
||||||
|
|
||||||
|
def __init__(self, defs=(), enums=()):
|
||||||
|
self._vs_defs = {}
|
||||||
|
self._vs_enums = {}
|
||||||
|
self._vs_namespaces = {}
|
||||||
|
for vsdef in defs:
|
||||||
|
self.addVStructDef(vsdef)
|
||||||
|
for enum in enums:
|
||||||
|
self.addVStructEnumeration(enum)
|
||||||
|
|
||||||
|
def __getattr__(self, name):
|
||||||
|
ns = self._vs_namespaces.get(name)
|
||||||
|
if ns != None:
|
||||||
|
return ns
|
||||||
|
|
||||||
|
vsdef = self._vs_defs.get(name)
|
||||||
|
if vsdef != None:
|
||||||
|
return VStructConstructor(self, name)
|
||||||
|
|
||||||
|
raise AttributeError, name
|
||||||
|
|
||||||
|
def addVStructEnumeration(self, enum):
|
||||||
|
self._vs_enums[enum[0]] = enum
|
||||||
|
|
||||||
|
def addVStructNamespace(self, name, builder):
|
||||||
|
self._vs_namespaces[name] = builder
|
||||||
|
|
||||||
|
def getVStructNamespaces(self):
|
||||||
|
return self._vs_namespaces.items()
|
||||||
|
|
||||||
|
def getVStructNamespaceNames(self):
|
||||||
|
return self._vs_namespaces.keys()
|
||||||
|
|
||||||
|
def hasVStructNamespace(self, namespace):
|
||||||
|
return self._vs_namespaces.get(namespace, None) != None
|
||||||
|
|
||||||
|
def getVStructNames(self, namespace=None):
|
||||||
|
if namespace == None:
|
||||||
|
return self._vs_defs.keys()
|
||||||
|
nsmod = self._vs_namespaces.get(namespace)
|
||||||
|
ret = []
|
||||||
|
for name in dir(nsmod):
|
||||||
|
nobj = getattr(nsmod, name)
|
||||||
|
if not inspect.isclass(nobj):
|
||||||
|
continue
|
||||||
|
if issubclass(nobj, vstruct.VStruct):
|
||||||
|
ret.append(name)
|
||||||
|
return ret
|
||||||
|
|
||||||
|
def addVStructDef(self, vsdef):
|
||||||
|
vsname = vsdef[0]
|
||||||
|
self._vs_defs[vsname] = vsdef
|
||||||
|
|
||||||
|
def buildVStruct(self, vsname):
|
||||||
|
# Check for a namespace
|
||||||
|
parts = vsname.split('.', 1)
|
||||||
|
if len(parts) == 2:
|
||||||
|
ns = self._vs_namespaces.get(parts[0])
|
||||||
|
if ns == None:
|
||||||
|
raise Exception('Namespace %s is not present! (need symbols?)' % parts[0])
|
||||||
|
|
||||||
|
# If a module gets added as a namespace, assume it has a class def...
|
||||||
|
if isinstance(ns, types.ModuleType):
|
||||||
|
cls = getattr(ns, parts[1])
|
||||||
|
if cls == None:
|
||||||
|
raise Exception('Unknown VStruct Definition: %s' % vsname)
|
||||||
|
return cls()
|
||||||
|
|
||||||
|
return ns.buildVStruct(parts[1])
|
||||||
|
|
||||||
|
vsdef = self._vs_defs.get(vsname)
|
||||||
|
if vsdef == None:
|
||||||
|
raise Exception('Unknown VStruct Definition: %s' % vsname)
|
||||||
|
|
||||||
|
vsname, vssize, vskids = vsdef
|
||||||
|
|
||||||
|
vs = vstruct.VStruct()
|
||||||
|
vs._vs_name = vsname
|
||||||
|
|
||||||
|
for fname, foffset, fsize, ftypename, fflags in vskids:
|
||||||
|
|
||||||
|
if fflags & VSFF_POINTER:
|
||||||
|
# FIXME support pointers with types!
|
||||||
|
if fsize == 4:
|
||||||
|
fieldval = vs_prim.v_ptr32()
|
||||||
|
|
||||||
|
elif fsize == 8:
|
||||||
|
fieldval = vs_prim.v_ptr64()
|
||||||
|
|
||||||
|
else:
|
||||||
|
raise Exception('Invalid Pointer Width: %d' % fsize)
|
||||||
|
|
||||||
|
elif fflags & VSFF_ARRAY:
|
||||||
|
if ftypename != None:
|
||||||
|
fieldval = vstruct.VArray()
|
||||||
|
while len(fieldval) < fsize:
|
||||||
|
fieldval.vsAddElement( self.buildVStruct(ftypename) )
|
||||||
|
else:
|
||||||
|
# FIXME actually handle arrays!
|
||||||
|
fieldval = vs_prim.v_bytes(size=fsize)
|
||||||
|
|
||||||
|
elif ftypename == None:
|
||||||
|
|
||||||
|
if fsize not in [1,2,4,8]:
|
||||||
|
#print 'Primitive Field Size: %d' % fsize
|
||||||
|
fieldval = v_bytes(size=fsize)
|
||||||
|
|
||||||
|
else:
|
||||||
|
fieldval = prim_types[fsize]()
|
||||||
|
|
||||||
|
else:
|
||||||
|
fieldval = self.buildVStruct(ftypename)
|
||||||
|
|
||||||
|
cursize = len(vs)
|
||||||
|
if foffset < cursize:
|
||||||
|
#print 'FIXME handle unions, overlaps, etc...'
|
||||||
|
continue
|
||||||
|
|
||||||
|
if foffset > cursize:
|
||||||
|
setattr(vs, '_pad%.4x' % foffset, vs_prim.v_bytes(size=(foffset-cursize)))
|
||||||
|
|
||||||
|
setattr(vs, fname, fieldval)
|
||||||
|
|
||||||
|
return vs
|
||||||
|
|
||||||
|
def genVStructPyCode(self):
|
||||||
|
ret = 'import vstruct\n'
|
||||||
|
ret += 'from vstruct.primitives import *'
|
||||||
|
ret += '\n\n'
|
||||||
|
|
||||||
|
for ename, esize, ekids in self._vs_enums.values():
|
||||||
|
ret += '%s = v_enum()\n' % ename
|
||||||
|
for kname, kval in ekids:
|
||||||
|
ret += '%s.%s = %d\n' % (ename,kname,kval)
|
||||||
|
ret += '\n\n'
|
||||||
|
|
||||||
|
|
||||||
|
for vsname, vsize, vskids in self._vs_defs.values():
|
||||||
|
ret += 'class %s(vstruct.VStruct):\n' % vsname
|
||||||
|
ret += ' def __init__(self):\n'
|
||||||
|
ret += ' vstruct.VStruct.__init__(self)\n'
|
||||||
|
offset = 0
|
||||||
|
for fname, foffset, fsize, ftypename, fflags in vskids:
|
||||||
|
|
||||||
|
if foffset < offset:
|
||||||
|
continue
|
||||||
|
|
||||||
|
if foffset > offset:
|
||||||
|
ret += ' self._pad%.4x = v_bytes(size=%d)\n' % (foffset, foffset-offset)
|
||||||
|
offset += (foffset - offset)
|
||||||
|
|
||||||
|
if fflags & VSFF_POINTER:
|
||||||
|
if fsize == 4:
|
||||||
|
fconst = 'v_ptr32()'
|
||||||
|
elif fsize == 8:
|
||||||
|
fconst = 'v_ptr64()'
|
||||||
|
else:
|
||||||
|
fconst = 'v_bytes(size=%d) # FIXME should be pointer!' % fsize
|
||||||
|
|
||||||
|
elif fflags & VSFF_ARRAY:
|
||||||
|
if ftypename != None:
|
||||||
|
'[ %s() for i in xrange( %d / len(%s())) ]' % (ftypename, fsize, ftypename)
|
||||||
|
else:
|
||||||
|
fconst = 'v_bytes(size=%d) # FIXME Unknown Array Type' % fsize
|
||||||
|
|
||||||
|
elif ftypename == None:
|
||||||
|
if fsize == 1:
|
||||||
|
fconst = 'v_uint8()'
|
||||||
|
elif fsize == 2:
|
||||||
|
fconst = 'v_uint16()'
|
||||||
|
elif fsize == 4:
|
||||||
|
fconst = 'v_uint32()'
|
||||||
|
elif fsize == 8:
|
||||||
|
fconst = 'v_uint64()'
|
||||||
|
else:
|
||||||
|
fconst = 'v_bytes(size=%d)' % fsize
|
||||||
|
else:
|
||||||
|
fconst = '%s()' % ftypename
|
||||||
|
|
||||||
|
|
||||||
|
ret += ' self.%s = %s\n' % (fname, fconst)
|
||||||
|
offset += fsize
|
||||||
|
ret += '\n\n'
|
||||||
|
|
||||||
|
return ret
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
# Parse windows structures from dll symbols...
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import platform
|
||||||
|
|
||||||
|
from pprint import pprint
|
||||||
|
|
||||||
|
import PE
|
||||||
|
import vtrace.platforms.win32 as vt_win32
|
||||||
|
|
||||||
|
p = PE.PE(file(sys.argv[1], 'rb'))
|
||||||
|
baseaddr = p.IMAGE_NT_HEADERS.OptionalHeader.ImageBase
|
||||||
|
osmajor = p.IMAGE_NT_HEADERS.OptionalHeader.MajorOperatingSystemVersion
|
||||||
|
osminor = p.IMAGE_NT_HEADERS.OptionalHeader.MinorOperatingSystemVersion
|
||||||
|
machine = p.IMAGE_NT_HEADERS.FileHeader.Machine
|
||||||
|
|
||||||
|
archname = PE.machine_names.get(machine)
|
||||||
|
|
||||||
|
parser = vt_win32.Win32SymbolParser(0xffffffff, sys.argv[1], baseaddr)
|
||||||
|
parser.parse()
|
||||||
|
|
||||||
|
t = parser._sym_types.values()
|
||||||
|
e = parser._sym_enums.values()
|
||||||
|
builder = VStructBuilder(defs=t, enums=e)
|
||||||
|
|
||||||
|
print '# Version: %d.%d' % (osmajor, osminor)
|
||||||
|
print '# Architecture: %s' % archname
|
||||||
|
print builder.genVStructPyCode()
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
|
||||||
|
# Import all local structure modules
|
||||||
|
import elf
|
||||||
|
import pe
|
||||||
|
import win32
|
||||||
|
|
|
@ -0,0 +1,162 @@
|
||||||
|
import vstruct
|
||||||
|
from vstruct.primitives import *
|
||||||
|
|
||||||
|
EI_NIDENT = 4
|
||||||
|
EI_PADLEN = 7
|
||||||
|
|
||||||
|
class Elf32(vstruct.VStruct):
|
||||||
|
def __init__(self):
|
||||||
|
vstruct.VStruct.__init__(self)
|
||||||
|
self.e_ident = v_bytes(EI_NIDENT)
|
||||||
|
self.e_class = v_uint8()
|
||||||
|
self.e_data = v_uint8()
|
||||||
|
self.e_fileversion = v_uint8()
|
||||||
|
self.e_osabi = v_uint8()
|
||||||
|
self.e_abiversio = v_uint8()
|
||||||
|
self.e_pad = v_bytes(EI_PADLEN)
|
||||||
|
self.e_type = v_uint16()
|
||||||
|
self.e_machine = v_uint16()
|
||||||
|
self.e_version = v_uint32()
|
||||||
|
self.e_entry = v_uint32()
|
||||||
|
self.e_phoff = v_uint32()
|
||||||
|
self.e_shoff = v_uint32()
|
||||||
|
self.e_flags = v_uint32()
|
||||||
|
self.e_ehsize = v_uint16()
|
||||||
|
self.e_phentsize = v_uint16()
|
||||||
|
self.e_phnum = v_uint16()
|
||||||
|
self.e_shentsize = v_uint16()
|
||||||
|
self.e_shnum = v_uint16()
|
||||||
|
self.e_shstrndx = v_uint16()
|
||||||
|
|
||||||
|
class Elf32Section(vstruct.VStruct):
|
||||||
|
def __init__(self):
|
||||||
|
vstruct.VStruct.__init__(self)
|
||||||
|
self.sh_name = v_uint32()
|
||||||
|
self.sh_type = v_uint32()
|
||||||
|
self.sh_flags = v_uint32()
|
||||||
|
self.sh_addr = v_uint32()
|
||||||
|
self.sh_offset = v_uint32()
|
||||||
|
self.sh_size = v_uint32()
|
||||||
|
self.sh_link = v_uint32()
|
||||||
|
self.sh_info = v_uint32()
|
||||||
|
self.sh_addralign = v_uint32()
|
||||||
|
self.sh_entsize = v_uint32()
|
||||||
|
|
||||||
|
class Elf32Pheader(vstruct.VStruct):
|
||||||
|
def __init__(self):
|
||||||
|
vstruct.VStruct.__init__(self)
|
||||||
|
self.p_type = v_uint32()
|
||||||
|
self.p_offset = v_uint32()
|
||||||
|
self.p_vaddr = v_uint32()
|
||||||
|
self.p_paddr = v_uint32()
|
||||||
|
self.p_filesz = v_uint32()
|
||||||
|
self.p_memsz = v_uint32()
|
||||||
|
self.p_flags = v_uint32()
|
||||||
|
self.p_align = v_uint32()
|
||||||
|
|
||||||
|
class Elf32Reloc(vstruct.VStruct):
|
||||||
|
def __init__(self):
|
||||||
|
vstruct.VStruct.__init__(self)
|
||||||
|
self.r_offset = v_ptr32()
|
||||||
|
self.r_info = v_uint32()
|
||||||
|
|
||||||
|
class Elf32Reloca(Elf32Reloc):
|
||||||
|
def __init__(self):
|
||||||
|
Elf32Reloc.__init__(self)
|
||||||
|
self.r_addend = v_uint32()
|
||||||
|
|
||||||
|
class Elf32Symbol(vstruct.VStruct):
|
||||||
|
def __init__(self):
|
||||||
|
vstruct.VStruct.__init__(self)
|
||||||
|
self.st_name = v_uint32()
|
||||||
|
self.st_value = v_uint32()
|
||||||
|
self.st_size = v_uint32()
|
||||||
|
self.st_info = v_uint8()
|
||||||
|
self.st_other = v_uint8()
|
||||||
|
self.st_shndx = v_uint16()
|
||||||
|
|
||||||
|
class Elf32Dynamic(vstruct.VStruct):
|
||||||
|
def __init__(self):
|
||||||
|
vstruct.VStruct.__init__(self)
|
||||||
|
self.d_tag = v_uint32()
|
||||||
|
self.d_value = v_uint32()
|
||||||
|
|
||||||
|
|
||||||
|
class Elf64(vstruct.VStruct):
|
||||||
|
def __init__(self):
|
||||||
|
vstruct.VStruct.__init__(self)
|
||||||
|
self.e_ident = v_bytes(EI_NIDENT)
|
||||||
|
self.e_class = v_uint8()
|
||||||
|
self.e_data = v_uint8()
|
||||||
|
self.e_fileversion = v_uint8()
|
||||||
|
self.e_osabi = v_uint8()
|
||||||
|
self.e_abiversio = v_uint8()
|
||||||
|
self.e_pad = v_bytes(EI_PADLEN)
|
||||||
|
self.e_type = v_uint16()
|
||||||
|
self.e_machine = v_uint16()
|
||||||
|
self.e_version = v_uint32()
|
||||||
|
self.e_entry = v_uint64()
|
||||||
|
self.e_phoff = v_uint64()
|
||||||
|
self.e_shoff = v_uint64()
|
||||||
|
self.e_flags = v_uint32()
|
||||||
|
self.e_ehsize = v_uint16()
|
||||||
|
self.e_phentsize = v_uint16()
|
||||||
|
self.e_phnum = v_uint16()
|
||||||
|
self.e_shentsize = v_uint16()
|
||||||
|
self.e_shnum = v_uint16()
|
||||||
|
self.e_shstrndx = v_uint16()
|
||||||
|
|
||||||
|
class Elf64Section(Elf32Section):
|
||||||
|
def __init__(self):
|
||||||
|
vstruct.VStruct.__init__(self)
|
||||||
|
self.sh_name = v_uint32()
|
||||||
|
self.sh_type = v_uint32()
|
||||||
|
self.sh_flags = v_uint64()
|
||||||
|
self.sh_addr = v_uint64()
|
||||||
|
self.sh_offset = v_uint64()
|
||||||
|
self.sh_size = v_uint64()
|
||||||
|
self.sh_link = v_uint32()
|
||||||
|
self.sh_info = v_uint32()
|
||||||
|
self.sh_addralign = v_uint64()
|
||||||
|
self.sh_entsize = v_uint64()
|
||||||
|
|
||||||
|
class Elf64Pheader(Elf32Pheader):
|
||||||
|
def __init__(self):
|
||||||
|
vstruct.VStruct.__init__(self)
|
||||||
|
self.p_type = v_uint32()
|
||||||
|
self.p_flags = v_uint32()
|
||||||
|
self.p_offset = v_uint64()
|
||||||
|
self.p_vaddr = v_uint64()
|
||||||
|
self.p_paddr = v_uint64()
|
||||||
|
self.p_filesz = v_uint64()
|
||||||
|
self.p_memsz = v_uint64()
|
||||||
|
self.p_align = v_uint64()
|
||||||
|
|
||||||
|
|
||||||
|
class Elf64Reloc(vstruct.VStruct):
|
||||||
|
def __init__(self):
|
||||||
|
vstruct.VStruct.__init__(self)
|
||||||
|
self.r_offset = v_ptr64()
|
||||||
|
self.r_info = v_uint64()
|
||||||
|
|
||||||
|
class Elf64Reloca(Elf64Reloc):
|
||||||
|
def __init__(self):
|
||||||
|
#Elf64Reloc.__init__(self)
|
||||||
|
vstruct.VStruct.__init__(self)
|
||||||
|
self.r_offset = v_uint64()
|
||||||
|
self.r_info = v_uint64()
|
||||||
|
self.r_addend = v_uint64()
|
||||||
|
|
||||||
|
class Elf64Symbol(vstruct.VStruct):
|
||||||
|
def __init__(self):
|
||||||
|
vstruct.VStruct.__init__(self)
|
||||||
|
self.st_name = v_uint32()
|
||||||
|
self.st_info = v_uint8()
|
||||||
|
self.st_other = v_uint8()
|
||||||
|
self.st_shndx = v_uint16()
|
||||||
|
self.st_value = v_uint64()
|
||||||
|
self.st_size = v_uint64()
|
||||||
|
|
||||||
|
class Elf64Dynamic(Elf32Dynamic):
|
||||||
|
pass
|
||||||
|
|
|
@ -0,0 +1,209 @@
|
||||||
|
"""
|
||||||
|
Initial module with supporting structures for windows
|
||||||
|
kernel serial debugging.
|
||||||
|
"""
|
||||||
|
|
||||||
|
import vstruct
|
||||||
|
from vstruct.primitives import *
|
||||||
|
|
||||||
|
# Main packet magic bytes and such
|
||||||
|
BREAKIN_PACKET = 0x62626262
|
||||||
|
BREAKIN_PACKET_BYTE = 0x62
|
||||||
|
PACKET_LEADER = 0x30303030
|
||||||
|
PACKET_LEADER_BYTE = 0x30
|
||||||
|
CONTROL_PACKET_LEADER = 0x69696969
|
||||||
|
CONTROL_PACKET_LEADER_BYTE = 0x69
|
||||||
|
PACKET_TRAILING_BYTE = 0xAA
|
||||||
|
|
||||||
|
pkt_magic_names = {
|
||||||
|
BREAKIN_PACKET:"Break Packet",
|
||||||
|
PACKET_LEADER:"Packet",
|
||||||
|
CONTROL_PACKET_LEADER:"Control Packet",
|
||||||
|
}
|
||||||
|
|
||||||
|
# Primary "packet types"
|
||||||
|
PACKET_TYPE_UNUSED = 0
|
||||||
|
PACKET_TYPE_KD_STATE_CHANGE32 = 1
|
||||||
|
PACKET_TYPE_KD_STATE_MANIPULATE = 2
|
||||||
|
PACKET_TYPE_KD_DEBUG_IO = 3
|
||||||
|
PACKET_TYPE_KD_ACKNOWLEDGE = 4
|
||||||
|
PACKET_TYPE_KD_RESEND = 5
|
||||||
|
PACKET_TYPE_KD_RESET = 6
|
||||||
|
PACKET_TYPE_KD_STATE_CHANGE64 = 7
|
||||||
|
PACKET_TYPE_KD_POLL_BREAKIN = 8
|
||||||
|
PACKET_TYPE_KD_TRACE_IO = 9
|
||||||
|
PACKET_TYPE_KD_CONTROL_REQUEST = 10
|
||||||
|
PACKET_TYPE_KD_FILE_IO = 11
|
||||||
|
PACKET_TYPE_MAX = 12
|
||||||
|
|
||||||
|
pkt_type_names = {
|
||||||
|
PACKET_TYPE_UNUSED:"Unused",
|
||||||
|
PACKET_TYPE_KD_STATE_CHANGE32:"State Change32",
|
||||||
|
PACKET_TYPE_KD_STATE_MANIPULATE:"Manipulate",
|
||||||
|
PACKET_TYPE_KD_DEBUG_IO:"Debug IO",
|
||||||
|
PACKET_TYPE_KD_ACKNOWLEDGE:"Ack",
|
||||||
|
PACKET_TYPE_KD_RESEND:"Resend",
|
||||||
|
PACKET_TYPE_KD_RESET:"Reset",
|
||||||
|
PACKET_TYPE_KD_STATE_CHANGE64:"State Change64",
|
||||||
|
PACKET_TYPE_KD_POLL_BREAKIN:"Breakin",
|
||||||
|
PACKET_TYPE_KD_TRACE_IO:"Trace IO",
|
||||||
|
PACKET_TYPE_KD_CONTROL_REQUEST:"Control Request",
|
||||||
|
PACKET_TYPE_KD_FILE_IO:"File IO",
|
||||||
|
PACKET_TYPE_MAX:"Max",
|
||||||
|
}
|
||||||
|
|
||||||
|
# Wait State Change Types
|
||||||
|
DbgKdMinimumStateChange = 0x00003030
|
||||||
|
DbgKdExceptionStateChange = 0x00003030
|
||||||
|
DbgKdLoadSymbolsStateChange = 0x00003031
|
||||||
|
DbgKdCommandStringStateChange = 0x00003032
|
||||||
|
DbgKdMaximumStateChange = 0x00003033
|
||||||
|
|
||||||
|
pkt_sub_wait_state_change = {
|
||||||
|
DbgKdMinimumStateChange:"DbgKdMinimumStateChange",
|
||||||
|
DbgKdExceptionStateChange:"DbgKdExceptionStateChange",
|
||||||
|
DbgKdLoadSymbolsStateChange:"DbgKdLoadSymbolsStateChange",
|
||||||
|
DbgKdCommandStringStateChange:"DbgKdCommandStringStateChange",
|
||||||
|
DbgKdMaximumStateChange:"DbgKdMaximumStateChange",
|
||||||
|
}
|
||||||
|
|
||||||
|
# Manipulate Types
|
||||||
|
DbgKdMinimumManipulate = 0x00003130
|
||||||
|
DbgKdReadVirtualMemoryApi = 0x00003130
|
||||||
|
DbgKdWriteVirtualMemoryApi = 0x00003131
|
||||||
|
DbgKdGetContextApi = 0x00003132
|
||||||
|
DbgKdSetContextApi = 0x00003133
|
||||||
|
DbgKdWriteBreakPointApi = 0x00003134
|
||||||
|
DbgKdRestoreBreakPointApi = 0x00003135
|
||||||
|
DbgKdContinueApi = 0x00003136
|
||||||
|
DbgKdReadControlSpaceApi = 0x00003137
|
||||||
|
DbgKdWriteControlSpaceApi = 0x00003138
|
||||||
|
DbgKdReadIoSpaceApi = 0x00003139
|
||||||
|
DbgKdWriteIoSpaceApi = 0x0000313A
|
||||||
|
DbgKdRebootApi = 0x0000313B
|
||||||
|
DbgKdContinueApi2 = 0x0000313C
|
||||||
|
DbgKdReadPhysicalMemoryApi = 0x0000313D
|
||||||
|
DbgKdWritePhysicalMemoryApi = 0x0000313E
|
||||||
|
DbgKdQuerySpecialCallsApi = 0x0000313F
|
||||||
|
DbgKdSetSpecialCallApi = 0x00003140
|
||||||
|
DbgKdClearSpecialCallsApi = 0x00003141
|
||||||
|
DbgKdSetInternalBreakPointApi = 0x00003142
|
||||||
|
DbgKdGetInternalBreakPointApi = 0x00003143
|
||||||
|
DbgKdReadIoSpaceExtendedApi = 0x00003144
|
||||||
|
DbgKdWriteIoSpaceExtendedApi = 0x00003145
|
||||||
|
DbgKdGetVersionApi = 0x00003146
|
||||||
|
DbgKdWriteBreakPointExApi = 0x00003147
|
||||||
|
DbgKdRestoreBreakPointExApi = 0x00003148
|
||||||
|
DbgKdCauseBugCheckApi = 0x00003149
|
||||||
|
DbgKdSwitchProcessor = 0x00003150
|
||||||
|
DbgKdPageInApi = 0x00003151
|
||||||
|
DbgKdReadMachineSpecificRegister = 0x00003152
|
||||||
|
DbgKdWriteMachineSpecificRegister = 0x00003153
|
||||||
|
OldVlm1 = 0x00003154
|
||||||
|
OldVlm2 = 0x00003155
|
||||||
|
DbgKdSearchMemoryApi = 0x00003156
|
||||||
|
DbgKdGetBusDataApi = 0x00003157
|
||||||
|
DbgKdSetBusDataApi = 0x00003158
|
||||||
|
DbgKdCheckLowMemoryApi = 0x00003159
|
||||||
|
DbgKdClearAllInternalBreakpointsApi = 0x0000315A
|
||||||
|
DbgKdFillMemoryApi = 0x0000315B
|
||||||
|
DbgKdQueryMemoryApi = 0x0000315C
|
||||||
|
DbgKdSwitchPartition = 0x0000315D
|
||||||
|
DbgKdMaximumManipulate = 0x0000315E
|
||||||
|
|
||||||
|
pkt_sub_manipulate = {
|
||||||
|
DbgKdMinimumManipulate:"DbgKdMinimumManipulate",
|
||||||
|
DbgKdReadVirtualMemoryApi:"DbgKdReadVirtualMemoryApi",
|
||||||
|
DbgKdWriteVirtualMemoryApi:"DbgKdWriteVirtualMemoryApi",
|
||||||
|
DbgKdGetContextApi:"DbgKdGetContextApi",
|
||||||
|
DbgKdSetContextApi:"DbgKdSetContextApi",
|
||||||
|
DbgKdWriteBreakPointApi:"DbgKdWriteBreakPointApi",
|
||||||
|
DbgKdRestoreBreakPointApi:"DbgKdRestoreBreakPointApi",
|
||||||
|
DbgKdContinueApi:"DbgKdContinueApi",
|
||||||
|
DbgKdReadControlSpaceApi:"DbgKdReadControlSpaceApi",
|
||||||
|
DbgKdWriteControlSpaceApi:"DbgKdWriteControlSpaceApi",
|
||||||
|
DbgKdReadIoSpaceApi:"DbgKdReadIoSpaceApi",
|
||||||
|
DbgKdWriteIoSpaceApi:"DbgKdWriteIoSpaceApi",
|
||||||
|
DbgKdRebootApi:"DbgKdRebootApi",
|
||||||
|
DbgKdContinueApi2:"DbgKdContinueApi2",
|
||||||
|
DbgKdReadPhysicalMemoryApi:"DbgKdReadPhysicalMemoryApi",
|
||||||
|
DbgKdWritePhysicalMemoryApi:"DbgKdWritePhysicalMemoryApi",
|
||||||
|
DbgKdQuerySpecialCallsApi:"DbgKdQuerySpecialCallsApi",
|
||||||
|
DbgKdSetSpecialCallApi:"DbgKdSetSpecialCallApi",
|
||||||
|
DbgKdClearSpecialCallsApi:"DbgKdClearSpecialCallsApi",
|
||||||
|
DbgKdSetInternalBreakPointApi:"DbgKdSetInternalBreakPointApi",
|
||||||
|
DbgKdGetInternalBreakPointApi:"DbgKdGetInternalBreakPointApi",
|
||||||
|
DbgKdReadIoSpaceExtendedApi:"DbgKdReadIoSpaceExtendedApi",
|
||||||
|
DbgKdWriteIoSpaceExtendedApi:"DbgKdWriteIoSpaceExtendedApi",
|
||||||
|
DbgKdGetVersionApi:"DbgKdGetVersionApi",
|
||||||
|
DbgKdWriteBreakPointExApi:"DbgKdWriteBreakPointExApi",
|
||||||
|
DbgKdRestoreBreakPointExApi:"DbgKdRestoreBreakPointExApi",
|
||||||
|
DbgKdCauseBugCheckApi:"DbgKdCauseBugCheckApi",
|
||||||
|
DbgKdSwitchProcessor:"DbgKdSwitchProcessor",
|
||||||
|
DbgKdPageInApi:"DbgKdPageInApi",
|
||||||
|
DbgKdReadMachineSpecificRegister:"DbgKdReadMachineSpecificRegister",
|
||||||
|
DbgKdWriteMachineSpecificRegister:"DbgKdWriteMachineSpecificRegister",
|
||||||
|
OldVlm1:"OldVlm1",
|
||||||
|
OldVlm2:"OldVlm2",
|
||||||
|
DbgKdSearchMemoryApi:"DbgKdSearchMemoryApi",
|
||||||
|
DbgKdGetBusDataApi:"DbgKdGetBusDataApi",
|
||||||
|
DbgKdSetBusDataApi:"DbgKdSetBusDataApi",
|
||||||
|
DbgKdCheckLowMemoryApi:"DbgKdCheckLowMemoryApi",
|
||||||
|
DbgKdClearAllInternalBreakpointsApi:"DbgKdClearAllInternalBreakpointsApi",
|
||||||
|
DbgKdFillMemoryApi:"DbgKdFillMemoryApi",
|
||||||
|
DbgKdQueryMemoryApi:"DbgKdQueryMemoryApi",
|
||||||
|
DbgKdSwitchPartition:"DbgKdSwitchPartition",
|
||||||
|
DbgKdMaximumManipulate:"DbgKdMaximumManipulate",
|
||||||
|
}
|
||||||
|
|
||||||
|
# Debug I/O Types
|
||||||
|
DbgKdPrintStringApi = 0x00003230
|
||||||
|
DbgKdGetStringApi = 0x00003231
|
||||||
|
|
||||||
|
# Control Report Flags
|
||||||
|
REPORT_INCLUDES_SEGS = 0x0001
|
||||||
|
REPORT_INCLUDES_CS = 0x0002
|
||||||
|
|
||||||
|
# Protocol Versions
|
||||||
|
DBGKD_64BIT_PROTOCOL_VERSION1 = 5
|
||||||
|
DBGKD_64BIT_PROTOCOL_VERSION2 = 6
|
||||||
|
|
||||||
|
# Query Memory Address Spaces
|
||||||
|
DBGKD_QUERY_MEMORY_VIRTUAL = 0
|
||||||
|
DBGKD_QUERY_MEMORY_PROCESS = 0
|
||||||
|
DBGKD_QUERY_MEMORY_SESSION = 1
|
||||||
|
DBGKD_QUERY_MEMORY_KERNEL = 2
|
||||||
|
|
||||||
|
# Query Memory Flags
|
||||||
|
DBGKD_QUERY_MEMORY_READ = 0x01
|
||||||
|
DBGKD_QUERY_MEMORY_WRITE = 0x02
|
||||||
|
DBGKD_QUERY_MEMORY_EXECUTE = 0x04
|
||||||
|
DBGKD_QUERY_MEMORY_FIXED = 0x08
|
||||||
|
|
||||||
|
ULONG = v_uint32
|
||||||
|
ULONG64 = v_uint64
|
||||||
|
BOOLEAN = v_uint32
|
||||||
|
|
||||||
|
class DBGKD_LOAD_SYMBOLS64(vstruct.VStruct):
|
||||||
|
def __init__(self):
|
||||||
|
vstruct.VStruct.__init__(self)
|
||||||
|
self._vs_field_align = True
|
||||||
|
self.PathNameLength = v_uint32()
|
||||||
|
self.BaseOfDll = v_uint64()
|
||||||
|
self.ProcessId = v_uint64()
|
||||||
|
self.CheckSum = v_uint32()
|
||||||
|
self.SizeOfImage = v_uint32()
|
||||||
|
#self.UnloadSymbols = v_uint8()
|
||||||
|
self.UnloadSymbols = v_uint32() # HACK must be 32 bit aligned
|
||||||
|
|
||||||
|
class DBGKD_WAIT_STATE_CHANGE64(vstruct.VStruct):
|
||||||
|
def __init__(self):
|
||||||
|
vstruct.VStruct.__init__(self)
|
||||||
|
self._vs_field_align = True
|
||||||
|
self.NewState = v_uint32()
|
||||||
|
self.ProcessorLevel = v_uint16()
|
||||||
|
self.Processor = v_uint16()
|
||||||
|
self.NumberProcessors = v_uint32()
|
||||||
|
self.Thread = v_uint64()
|
||||||
|
self.ProgramCounter = v_uint64()
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
'''
|
||||||
|
Structure definitions for the OSX MachO binary format.
|
||||||
|
'''
|
||||||
|
|
||||||
|
import vstruct
|
||||||
|
import vstruct.primitives as vs_prim
|
||||||
|
|
||||||
|
from vstruct.defs.macho.const import *
|
||||||
|
|
||||||
|
from vstruct.defs.macho.fat import *
|
||||||
|
from vstruct.defs.macho.loader import *
|
||||||
|
|
|
@ -0,0 +1,128 @@
|
||||||
|
|
||||||
|
# Fat Defines...
|
||||||
|
FAT_MAGIC = 0xcafebabe
|
||||||
|
FAT_CIGAM = 0xbebafec #NXSwapLong(FAT_MAGIC)
|
||||||
|
|
||||||
|
MH_MAGIC = 0xfeedface # the mach magic number
|
||||||
|
MH_CIGAM = 0xcefaedfe # NXSwapInt(MH_MAGIC)
|
||||||
|
MH_MAGIC_64 = 0xfeedfacf # the 64-bit mach magic number
|
||||||
|
MH_CIGAM_64 = 0xcffaedfe # NXSwapInt(MH_MAGIC_64)
|
||||||
|
MH_OBJECT = 0x1 # relocatable object file
|
||||||
|
MH_EXECUTE = 0x2 # demand paged executable file
|
||||||
|
MH_FVMLIB = 0x3 # fixed VM shared library file
|
||||||
|
MH_CORE = 0x4 # core file
|
||||||
|
MH_PRELOAD = 0x5 # preloaded executable file
|
||||||
|
MH_DYLIB = 0x6 # dynamically bound shared library
|
||||||
|
MH_DYLINKER = 0x7 # dynamic link editor
|
||||||
|
MH_BUNDLE = 0x8 # dynamically bound bundle file
|
||||||
|
MH_DYLIB_STUB = 0x9 # shared library stub for static
|
||||||
|
MH_DSYM = 0xa # companion file with only debug
|
||||||
|
MH_NOUNDEFS = 0x1 # the object file has no undefinedreferences
|
||||||
|
MH_INCRLINK = 0x2 # the object file is the output of anincremental link against a base fileand can't be link edited again
|
||||||
|
MH_DYLDLINK = 0x4 # the object file is input for thedynamic linker and can't be staticlylink edited again
|
||||||
|
MH_BINDATLOAD = 0x8 # the object file's undefinedreferences are bound by the dynamiclinker when loaded.
|
||||||
|
MH_PREBOUND = 0x10 # the file has its dynamic undefinedreferences prebound.
|
||||||
|
MH_SPLIT_SEGS = 0x20 # the file has its read-only andread-write segments split
|
||||||
|
MH_LAZY_INIT = 0x40 # the shared library init routine isto be run lazily via catching memoryfaults to its writeable segments(obsolete)
|
||||||
|
MH_TWOLEVEL = 0x80 # the image is using two-level namespace bindings
|
||||||
|
MH_FORCE_FLAT = 0x100 # the executable is forcing all imagesto use flat name space bindings
|
||||||
|
MH_NOMULTIDEFS = 0x200 # this umbrella guarantees no multipledefintions of symbols in itssub-images so the two-level namespacehints can always be used.
|
||||||
|
MH_NOFIXPREBINDING = 0x400 # do not have dyld notify theprebinding agent about thisexecutable
|
||||||
|
MH_PREBINDABLE = 0x800 # the binary is not prebound but canhave its prebinding redone. only usedwhen MH_PREBOUND is not set.
|
||||||
|
MH_ALLMODSBOUND = 0x1000 # this binary binds toall two-level namespace modules ofits dependent libraries. only usedwhen MH_PREBINDABLE and MH_TWOLEVELare both set.
|
||||||
|
MH_CANONICAL = 0x4000 # the binary has been canonicalizedvia the unprebind operation
|
||||||
|
MH_WEAK_DEFINES = 0x8000 # the final linked image containsexternal weak symbols
|
||||||
|
MH_BINDS_TO_WEAK = 0x10000 # the final linked image usesweak symbols
|
||||||
|
MH_ROOT_SAFE = 0x40000 # When this bit is set, the binarydeclares it is safe for use inprocesses with uid zero
|
||||||
|
MH_SETUID_SAFE = 0x80000 # When this bit is set, the binarydeclares it is safe for use inprocesses when issetugid() is true
|
||||||
|
MH_NO_REEXPORTED_DYLIBS = 0x100000 # When this bit is set on a dylib,the static linker does not need toexamine dependent dylibs to seeif any are re-exported
|
||||||
|
MH_PIE = 0x200000 # When this bit is set, the OS willload the main executable at arandom address. Only used inMH_EXECUTE filetypes.
|
||||||
|
|
||||||
|
# Constants for the cmd field of all load commands, the type
|
||||||
|
LC_REQ_DYLD = 0x80000000 # When this bit is set, the OS willload the main executable at arandom address. Only used inMH_EXECUTE filetypes.
|
||||||
|
LC_SEGMENT = 0x1 # segment of this file to be mapped
|
||||||
|
LC_SYMTAB = 0x2 # link-edit stab symbol table info
|
||||||
|
LC_SYMSEG = 0x3 # link-edit gdb symbol table info (obsolete)
|
||||||
|
LC_THREAD = 0x4 # thread
|
||||||
|
LC_UNIXTHREAD = 0x5 # unix thread (includes a stack)
|
||||||
|
LC_LOADFVMLIB = 0x6 # load a specified fixed VM shared library
|
||||||
|
LC_IDFVMLIB = 0x7 # fixed VM shared library identification
|
||||||
|
LC_IDENT = 0x8 # object identification info (obsolete)
|
||||||
|
LC_FVMFILE = 0x9 # fixed VM file inclusion (internal use)
|
||||||
|
LC_PREPAGE = 0xa # prepage command (internal use)
|
||||||
|
LC_DYSYMTAB = 0xb # dynamic link-edit symbol table info
|
||||||
|
LC_LOAD_DYLIB = 0xc # load a dynamically linked shared library
|
||||||
|
LC_ID_DYLIB = 0xd # dynamically linked shared lib ident
|
||||||
|
LC_LOAD_DYLINKER = 0xe # load a dynamic linker
|
||||||
|
LC_ID_DYLINKER = 0xf # dynamic linker identification
|
||||||
|
LC_PREBOUND_DYLIB = 0x10 # modules prebound for a dynamically
|
||||||
|
LC_ROUTINES = 0x11 # image routines
|
||||||
|
LC_SUB_FRAMEWORK = 0x12 # sub framework
|
||||||
|
LC_SUB_UMBRELLA = 0x13 # sub umbrella
|
||||||
|
LC_SUB_CLIENT = 0x14 # sub client
|
||||||
|
LC_SUB_LIBRARY = 0x15 # sub library
|
||||||
|
LC_TWOLEVEL_HINTS = 0x16 # two-level namespace lookup hints
|
||||||
|
LC_PREBIND_CKSUM = 0x17 # prebind checksum
|
||||||
|
LC_SEGMENT_64 = 0x19 # 64-bit segment of this file to bemapped
|
||||||
|
LC_ROUTINES_64 = 0x1a # 64-bit image routines
|
||||||
|
LC_UUID = 0x1b # the uuid
|
||||||
|
LC_CODE_SIGNATURE = 0x1d # local of code signature
|
||||||
|
LC_SEGMENT_SPLIT_INFO = 0x1e # local of info to split segments
|
||||||
|
LC_LAZY_LOAD_DYLIB = 0x20 # delay load of dylib until first use
|
||||||
|
LC_ENCRYPTION_INFO = 0x21 # encrypted segment information
|
||||||
|
SG_HIGHVM = 0x1 # the file contents for this segment is forthe high part of the VM space, the low partis zero filled (for stacks in core files)
|
||||||
|
SG_FVMLIB = 0x2 # this segment is the VM that is allocated bya fixed VM library, for overlap checking inthe link editor
|
||||||
|
SG_NORELOC = 0x4 # this segment has nothing that was relocatedin it and nothing relocated to it, that isit maybe safely replaced without relocation
|
||||||
|
SG_PROTECTED_VERSION_1 = 0x8 # This segment is protected. If thesegment starts at file offset 0, thefirst page of the segment is notprotected. All other pages of thesegment are protected.
|
||||||
|
|
||||||
|
|
||||||
|
SECTION_TYPE = 0x000000ff # 256 section types
|
||||||
|
SECTION_ATTRIBUTES = 0xffffff00 # 24 section attributes
|
||||||
|
S_REGULAR = 0x0 # regular section
|
||||||
|
S_ZEROFILL = 0x1 # zero fill on demand section
|
||||||
|
S_CSTRING_LITERALS = 0x2 # section with only literal C strings
|
||||||
|
S_4BYTE_LITERALS = 0x3 # section with only 4 byte literals
|
||||||
|
S_8BYTE_LITERALS = 0x4 # section with only 8 byte literals
|
||||||
|
S_LITERAL_POINTERS = 0x5 # section with only pointers to
|
||||||
|
S_NON_LAZY_SYMBOL_POINTERS = 0x6 # section with only non-lazysymbol pointers
|
||||||
|
S_LAZY_SYMBOL_POINTERS = 0x7 # section with only lazy symbolpointers
|
||||||
|
S_SYMBOL_STUBS = 0x8 # section with only symbolstubs, byte size of stub inthe reserved2 field
|
||||||
|
S_MOD_INIT_FUNC_POINTERS = 0x9 # section with only functionpointers for initialization
|
||||||
|
S_MOD_TERM_FUNC_POINTERS = 0xa # section with only functionpointers for termination
|
||||||
|
S_COALESCED = 0xb # section contains symbols thatare to be coalesced
|
||||||
|
S_GB_ZEROFILL = 0xc # zero fill on demand section(that can be larger than 4gigabytes)
|
||||||
|
S_INTERPOSING = 0xd # section with only pairs offunction pointers forinterposing
|
||||||
|
S_16BYTE_LITERALS = 0xe # section with only 16 byteliterals
|
||||||
|
S_DTRACE_DOF = 0xf # section containsDTrace Object Format
|
||||||
|
S_LAZY_DYLIB_SYMBOL_POINTERS = 0x10 # section with only lazysymbol pointers to lazyloaded dylibs
|
||||||
|
SECTION_ATTRIBUTES_USR = 0xff000000 # User setable attributes
|
||||||
|
S_ATTR_PURE_INSTRUCTIONS = 0x80000000 # section contains only truemachine instructions
|
||||||
|
S_ATTR_NO_TOC = 0x40000000 # section contains coalescedsymbols that are not to bein a ranlib table ofcontents
|
||||||
|
S_ATTR_STRIP_STATIC_SYMS = 0x20000000 # ok to strip static symbolsin this section in fileswith the MH_DYLDLINK flag
|
||||||
|
S_ATTR_NO_DEAD_STRIP = 0x10000000 # no dead stripping
|
||||||
|
S_ATTR_LIVE_SUPPORT = 0x08000000 # blocks are live if theyreference live blocks
|
||||||
|
S_ATTR_SELF_MODIFYING_CODE = 0x04000000 # Used with i386 code stubswritten on by dyld
|
||||||
|
S_ATTR_DEBUG = 0x02000000 # a debug section
|
||||||
|
SECTION_ATTRIBUTES_SYS = 0x00ffff00 # system setable attributes
|
||||||
|
S_ATTR_SOME_INSTRUCTIONS = 0x00000400 # section contains somemachine instructions
|
||||||
|
S_ATTR_EXT_RELOC = 0x00000200 # section has externalrelocation entries
|
||||||
|
S_ATTR_LOC_RELOC = 0x00000100 # section has localrelocation entries
|
||||||
|
INDIRECT_SYMBOL_LOCAL = 0x80000000 # section has localrelocation entries
|
||||||
|
INDIRECT_SYMBOL_ABS = 0x40000000 # section has localrelocation entries
|
||||||
|
|
||||||
|
CPU_TYPE_ANY = -1
|
||||||
|
CPU_TYPE_VAX = 1
|
||||||
|
CPU_TYPE_MC680 = 6
|
||||||
|
CPU_TYPE_X86 = 7
|
||||||
|
CPU_TYPE_X86_64 = 0x01000007
|
||||||
|
#CPU_TYPE_MIPS ((cpu_type_t) 8) */
|
||||||
|
#CPU_TYPE_MC98000 ((cpu_type_t) 10)
|
||||||
|
#CPU_TYPE_HPPA ((cpu_type_t) 11)
|
||||||
|
#CPU_TYPE_ARM ((cpu_type_t) 12)
|
||||||
|
#CPU_TYPE_MC88000 ((cpu_type_t) 13)
|
||||||
|
#CPU_TYPE_SPARC ((cpu_type_t) 14)
|
||||||
|
#CPU_TYPE_I860 ((cpu_type_t) 15)
|
||||||
|
#CPU_TYPE_ALPHA ((cpu_type_t) 16) */
|
||||||
|
#CPU_TYPE_POWERPC ((cpu_type_t) 18)
|
||||||
|
#CPU_TYPE_POWERPC64 (CPU_TYPE_POWERPC | CPU_ARCH_ABI64)
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
|
||||||
|
import vstruct
|
||||||
|
import vstruct.primitives as vs_prim
|
||||||
|
|
||||||
|
class fat_header(vstruct.VStruct):
|
||||||
|
def __init__(self):
|
||||||
|
vstruct.VStruct.__init__(self, bigend=True)
|
||||||
|
self.magic = vs_prim.v_uint32()
|
||||||
|
self.nfat_arch = vs_prim.v_uint32()
|
||||||
|
|
||||||
|
class fat_arch(vstruct.VStruct):
|
||||||
|
def __init__(self):
|
||||||
|
vstruct.VStruct.__init__(self, bigend=True)
|
||||||
|
self.cputype = vs_prim.v_uint32() # cpu specifier (int) */
|
||||||
|
self.cpusubtype = vs_prim.v_uint32() # machine specifier (int) */
|
||||||
|
self.offset = vs_prim.v_uint32() # file offset to this object file */
|
||||||
|
self.size = vs_prim.v_uint32() # size of this object file */
|
||||||
|
self.align = vs_prim.v_uint32() # alignment as a power of 2 */
|
||||||
|
|
|
@ -0,0 +1,425 @@
|
||||||
|
import vstruct
|
||||||
|
import vstruct.primitives as vs_prim
|
||||||
|
|
||||||
|
vm_prot_t = vs_prim.v_uint32
|
||||||
|
cpu_type_t = vs_prim.v_uint32
|
||||||
|
cpu_subtype_t = vs_prim.v_uint32
|
||||||
|
lc_str = vs_prim.v_uint32
|
||||||
|
|
||||||
|
class mach_header(vstruct.VStruct):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
vstruct.VStruct.__init__(self)
|
||||||
|
self.magic = vs_prim.v_uint32() # mach magic number identifier
|
||||||
|
self.cputype = cpu_type_t() # cpu specifier
|
||||||
|
self.cpusubtype = cpu_subtype_t() # machine specifier
|
||||||
|
self.filetype = vs_prim.v_uint32() # type of file
|
||||||
|
self.ncmds = vs_prim.v_uint32() # number of load commands
|
||||||
|
self.sizeofcmds = vs_prim.v_uint32() # the size of all the load commands
|
||||||
|
self.flags = vs_prim.v_uint32() # flags
|
||||||
|
|
||||||
|
|
||||||
|
class mach_header_64(vstruct.VStruct):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
vstruct.VStruct.__init__(self)
|
||||||
|
self.magic = vs_prim.v_uint32() # mach magic number identifier
|
||||||
|
self.cputype = cpu_type_t() # cpu specifier
|
||||||
|
self.cpusubtype = cpu_subtype_t() # machine specifier
|
||||||
|
self.filetype = vs_prim.v_uint32() # type of file
|
||||||
|
self.ncmds = vs_prim.v_uint32() # number of load commands
|
||||||
|
self.sizeofcmds = vs_prim.v_uint32() # the size of all the load commands
|
||||||
|
self.flags = vs_prim.v_uint32() # flags
|
||||||
|
self.reserved = vs_prim.v_uint32() # reserved
|
||||||
|
|
||||||
|
|
||||||
|
class load_command(vstruct.VStruct):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
vstruct.VStruct.__init__(self)
|
||||||
|
self.cmd = vs_prim.v_uint32() # type of load command
|
||||||
|
self.cmdsize = vs_prim.v_uint32() # total size of command in bytes
|
||||||
|
|
||||||
|
class segment_command(vstruct.VStruct):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
vstruct.VStruct.__init__(self)
|
||||||
|
self.cmd = vs_prim.v_uint32() # LC_SEGMENT
|
||||||
|
self.cmdsize = vs_prim.v_uint32() # includes sizeof section structs
|
||||||
|
self.segname[16] = vs_prim.v_uint8() # segment name
|
||||||
|
self.vmaddr = vs_prim.v_uint32() # memory address of this segment
|
||||||
|
self.vmsize = vs_prim.v_uint32() # memory size of this segment
|
||||||
|
self.fileoff = vs_prim.v_uint32() # file offset of this segment
|
||||||
|
self.filesize = vs_prim.v_uint32() # amount to map from the file
|
||||||
|
self.maxprot = vm_prot_t() # maximum VM protection
|
||||||
|
self.initprot = vm_prot_t() # initial VM protection
|
||||||
|
self.nsects = vs_prim.v_uint32() # number of sections in segment
|
||||||
|
self.flags = vs_prim.v_uint32() # flags
|
||||||
|
|
||||||
|
|
||||||
|
class segment_command_64(vstruct.VStruct):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
vstruct.VStruct.__init__(self)
|
||||||
|
self.cmd = vs_prim.v_uint32() # LC_SEGMENT_64
|
||||||
|
self.cmdsize = vs_prim.v_uint32() # includes sizeof section_64 structs
|
||||||
|
self.segname[16] = vs_prim.v_uint8() # segment name
|
||||||
|
self.vmaddr = vs_prim.v_uint64() # memory address of this segment
|
||||||
|
self.vmsize = vs_prim.v_uint64() # memory size of this segment
|
||||||
|
self.fileoff = vs_prim.v_uint64() # file offset of this segment
|
||||||
|
self.filesize = vs_prim.v_uint64() # amount to map from the file
|
||||||
|
self.maxprot = vm_prot_t() # maximum VM protection
|
||||||
|
self.initprot = vm_prot_t() # initial VM protection
|
||||||
|
self.nsects = vs_prim.v_uint32() # number of sections in segment
|
||||||
|
self.flags = vs_prim.v_uint32() # flags
|
||||||
|
|
||||||
|
|
||||||
|
class section(vstruct.VStruct):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
vstruct.VStruct.__init__(self)
|
||||||
|
self.sectname[16] = vs_prim.v_uint8() # name of this section
|
||||||
|
self.segname[16] = vs_prim.v_uint8() # segment this section goes in
|
||||||
|
self.addr = vs_prim.v_uint32() # memory address of this section
|
||||||
|
self.size = vs_prim.v_uint32() # size in bytes of this section
|
||||||
|
self.offset = vs_prim.v_uint32() # file offset of this section
|
||||||
|
self.align = vs_prim.v_uint32() # section alignment (power of 2)
|
||||||
|
self.reloff = vs_prim.v_uint32() # file offset of relocation entries
|
||||||
|
self.nreloc = vs_prim.v_uint32() # number of relocation entries
|
||||||
|
self.flags = vs_prim.v_uint32() # flags (section type and attributes)
|
||||||
|
self.reserved1 = vs_prim.v_uint32() # reserved (for offset or index)
|
||||||
|
self.reserved2 = vs_prim.v_uint32() # reserved (for count or sizeof)
|
||||||
|
|
||||||
|
|
||||||
|
class section_64(vstruct.VStruct):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
vstruct.VStruct.__init__(self)
|
||||||
|
self.sectname[16] = vs_prim.v_uint8() # name of this section
|
||||||
|
self.segname[16] = vs_prim.v_uint8() # segment this section goes in
|
||||||
|
self.addr = vs_prim.v_uint64() # memory address of this section
|
||||||
|
self.size = vs_prim.v_uint64() # size in bytes of this section
|
||||||
|
self.offset = vs_prim.v_uint32() # file offset of this section
|
||||||
|
self.align = vs_prim.v_uint32() # section alignment (power of 2)
|
||||||
|
self.reloff = vs_prim.v_uint32() # file offset of relocation entries
|
||||||
|
self.nreloc = vs_prim.v_uint32() # number of relocation entries
|
||||||
|
self.flags = vs_prim.v_uint32() # flags (section type and attributes)
|
||||||
|
self.reserved1 = vs_prim.v_uint32() # reserved (for offset or index)
|
||||||
|
self.reserved2 = vs_prim.v_uint32() # reserved (for count or sizeof)
|
||||||
|
self.reserved3 = vs_prim.v_uint32() # reserved
|
||||||
|
|
||||||
|
|
||||||
|
class fvmlib(vstruct.VStruct):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
vstruct.VStruct.__init__(self)
|
||||||
|
self.name = lc_str() # library's target pathname
|
||||||
|
self.minor_version = vs_prim.v_uint32() # library's minor version number
|
||||||
|
self.header_addr = vs_prim.v_uint32() # library's header address
|
||||||
|
|
||||||
|
|
||||||
|
class fvmlib_command(vstruct.VStruct):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
vstruct.VStruct.__init__(self)
|
||||||
|
self.cmd = vs_prim.v_uint32() # LC_IDFVMLIB or LC_LOADFVMLIB
|
||||||
|
self.cmdsize = vs_prim.v_uint32() # includes pathname string
|
||||||
|
self.fvmlib = fvmlib() # the library identification
|
||||||
|
|
||||||
|
|
||||||
|
class dylib(vstruct.VStruct):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
vstruct.VStruct.__init__(self)
|
||||||
|
self.name = lc_str() # library's path name
|
||||||
|
self.timestamp = vs_prim.v_uint32() # library's build time stamp
|
||||||
|
self.current_version = vs_prim.v_uint32() # library's current version number
|
||||||
|
self.compatibility_version = vs_prim.v_uint32() # library's compatibility vers number
|
||||||
|
|
||||||
|
|
||||||
|
class dylib_command(vstruct.VStruct):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
vstruct.VStruct.__init__(self)
|
||||||
|
self.cmd = vs_prim.v_uint32() # LC_ID_DYLIB, LC_LOAD_{,WEAK_}DYLIB, LC_REEXPORT_DYLIB
|
||||||
|
self.cmdsize = vs_prim.v_uint32() # includes pathname string
|
||||||
|
self.dylib = dylib() # the library identification
|
||||||
|
|
||||||
|
|
||||||
|
class sub_framework_command(vstruct.VStruct):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
vstruct.VStruct.__init__(self)
|
||||||
|
self.cmd = vs_prim.v_uint32() # LC_SUB_FRAMEWORK
|
||||||
|
self.cmdsize = vs_prim.v_uint32() # includes umbrella string
|
||||||
|
self.umbrella = lc_str() # the umbrella framework name
|
||||||
|
|
||||||
|
|
||||||
|
class sub_client_command(vstruct.VStruct):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
vstruct.VStruct.__init__(self)
|
||||||
|
self.cmd = vs_prim.v_uint32() # LC_SUB_CLIENT
|
||||||
|
self.cmdsize = vs_prim.v_uint32() # includes client string
|
||||||
|
self.client = lc_str() # the client name
|
||||||
|
|
||||||
|
|
||||||
|
class sub_umbrella_command(vstruct.VStruct):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
vstruct.VStruct.__init__(self)
|
||||||
|
self.cmd = vs_prim.v_uint32() # LC_SUB_UMBRELLA
|
||||||
|
self.cmdsize = vs_prim.v_uint32() # includes sub_umbrella string
|
||||||
|
self.sub_umbrella = lc_str() # the sub_umbrella framework name
|
||||||
|
|
||||||
|
|
||||||
|
class sub_library_command(vstruct.VStruct):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
vstruct.VStruct.__init__(self)
|
||||||
|
self.cmd = vs_prim.v_uint32() # LC_SUB_LIBRARY
|
||||||
|
self.cmdsize = vs_prim.v_uint32() # includes sub_library string
|
||||||
|
self.sub_library = lc_str() # the sub_library name
|
||||||
|
|
||||||
|
|
||||||
|
class prebound_dylib_command(vstruct.VStruct):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
vstruct.VStruct.__init__(self)
|
||||||
|
self.cmd = vs_prim.v_uint32() # LC_PREBOUND_DYLIB
|
||||||
|
self.cmdsize = vs_prim.v_uint32() # includes strings
|
||||||
|
self.name = lc_str() # library's path name
|
||||||
|
self.nmodules = vs_prim.v_uint32() # number of modules in library
|
||||||
|
self.linked_modules = lc_str() # bit vector of linked modules
|
||||||
|
|
||||||
|
|
||||||
|
class dylinker_command(vstruct.VStruct):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
vstruct.VStruct.__init__(self)
|
||||||
|
self.cmd = vs_prim.v_uint32() # LC_ID_DYLINKER or LC_LOAD_DYLINKER
|
||||||
|
self.cmdsize = vs_prim.v_uint32() # includes pathname string
|
||||||
|
self.name = lc_str() # dynamic linker's path name
|
||||||
|
|
||||||
|
|
||||||
|
class thread_command(vstruct.VStruct):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
vstruct.VStruct.__init__(self)
|
||||||
|
self.cmd = vs_prim.v_uint32() # LC_THREAD or LC_UNIXTHREAD
|
||||||
|
self.cmdsize = vs_prim.v_uint32() # total size of this command
|
||||||
|
|
||||||
|
|
||||||
|
class routines_command(vstruct.VStruct):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
vstruct.VStruct.__init__(self)
|
||||||
|
self.cmd = vs_prim.v_uint32() # LC_ROUTINES
|
||||||
|
self.cmdsize = vs_prim.v_uint32() # total size of this command
|
||||||
|
self.init_address = vs_prim.v_uint32() # address of initialization routine
|
||||||
|
self.init_module = vs_prim.v_uint32() # index into the module table that
|
||||||
|
self.reserved1 = vs_prim.vs_prim.v_uint32()
|
||||||
|
self.reserved2 = vs_prim.vs_prim.v_uint32()
|
||||||
|
self.reserved3 = vs_prim.vs_prim.v_uint32()
|
||||||
|
self.reserved4 = vs_prim.vs_prim.v_uint32()
|
||||||
|
self.reserved5 = vs_prim.vs_prim.v_uint32()
|
||||||
|
self.reserved6 = vs_prim.vs_prim.v_uint32()
|
||||||
|
|
||||||
|
|
||||||
|
class routines_command_64(vstruct.VStruct):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
vstruct.VStruct.__init__(self)
|
||||||
|
self.cmd = vs_prim.v_uint32() # LC_ROUTINES_64
|
||||||
|
self.cmdsize = vs_prim.v_uint32() # total size of this command
|
||||||
|
self.init_address = vs_prim.v_uint64() # address of initialization routine
|
||||||
|
self.init_module = vs_prim.v_uint64() # index into the module table that
|
||||||
|
self.reserved1 = vs_prim.vs_prim.v_uint64()
|
||||||
|
self.reserved2 = vs_prim.vs_prim.v_uint64()
|
||||||
|
self.reserved3 = vs_prim.vs_prim.v_uint64()
|
||||||
|
self.reserved4 = vs_prim.vs_prim.v_uint64()
|
||||||
|
self.reserved5 = vs_prim.vs_prim.v_uint64()
|
||||||
|
self.reserved6 = vs_prim.vs_prim.v_uint64()
|
||||||
|
|
||||||
|
|
||||||
|
class symtab_command(vstruct.VStruct):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
vstruct.VStruct.__init__(self)
|
||||||
|
self.cmd = vs_prim.v_uint32() # LC_SYMTAB
|
||||||
|
self.cmdsize = vs_prim.v_uint32() # sizeof(struct symtab_command)
|
||||||
|
self.symoff = vs_prim.v_uint32() # symbol table offset
|
||||||
|
self.nsyms = vs_prim.v_uint32() # number of symbol table entries
|
||||||
|
self.stroff = vs_prim.v_uint32() # string table offset
|
||||||
|
self.strsize = vs_prim.v_uint32() # string table size in bytes
|
||||||
|
|
||||||
|
|
||||||
|
class dysymtab_command(vstruct.VStruct):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
vstruct.VStruct.__init__(self)
|
||||||
|
self.cmd = vs_prim.v_uint32() # LC_DYSYMTAB
|
||||||
|
self.cmdsize = vs_prim.v_uint32() # sizeof(struct dysymtab_command)
|
||||||
|
self.ilocalsym = vs_prim.v_uint32() # index to local symbols
|
||||||
|
self.nlocalsym = vs_prim.v_uint32() # number of local symbols
|
||||||
|
self.iextdefsym = vs_prim.v_uint32() # index to externally defined symbols
|
||||||
|
self.nextdefsym = vs_prim.v_uint32() # number of externally defined symbols
|
||||||
|
self.iundefsym = vs_prim.v_uint32() # index to undefined symbols
|
||||||
|
self.nundefsym = vs_prim.v_uint32() # number of undefined symbols
|
||||||
|
self.tocoff = vs_prim.v_uint32() # file offset to table of contents
|
||||||
|
self.ntoc = vs_prim.v_uint32() # number of entries in table of contents
|
||||||
|
self.modtaboff = vs_prim.v_uint32() # file offset to module table
|
||||||
|
self.nmodtab = vs_prim.v_uint32() # number of module table entries
|
||||||
|
self.extrefsymoff = vs_prim.v_uint32() # offset to referenced symbol table
|
||||||
|
self.nextrefsyms = vs_prim.v_uint32() # number of referenced symbol table entries
|
||||||
|
self.indirectsymoff = vs_prim.v_uint32() # file offset to the indirect symbol table
|
||||||
|
self.nindirectsyms = vs_prim.v_uint32() # number of indirect symbol table entries
|
||||||
|
self.extreloff = vs_prim.v_uint32() # offset to external relocation entries
|
||||||
|
self.nextrel = vs_prim.v_uint32() # number of external relocation entries
|
||||||
|
self.locreloff = vs_prim.v_uint32() # offset to local relocation entries
|
||||||
|
self.nlocrel = vs_prim.v_uint32() # number of local relocation entries
|
||||||
|
|
||||||
|
|
||||||
|
class dylib_table_of_contents(vstruct.VStruct):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
vstruct.VStruct.__init__(self)
|
||||||
|
self.symbol_index = vs_prim.v_uint32() # the defined external symbol (index into the symbol table)
|
||||||
|
self.module_index = vs_prim.v_uint32() # index into the module table this symbol is defined in
|
||||||
|
|
||||||
|
|
||||||
|
class dylib_module(vstruct.VStruct):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
vstruct.VStruct.__init__(self)
|
||||||
|
self.module_name = vs_prim.v_uint32() # the module name (index into string table)
|
||||||
|
self.iextdefsym = vs_prim.v_uint32() # index into externally defined symbols
|
||||||
|
self.nextdefsym = vs_prim.v_uint32() # number of externally defined symbols
|
||||||
|
self.irefsym = vs_prim.v_uint32() # index into reference symbol table
|
||||||
|
self.nrefsym = vs_prim.v_uint32() # number of reference symbol table entries
|
||||||
|
self.ilocalsym = vs_prim.v_uint32() # index into symbols for local symbols
|
||||||
|
self.nlocalsym = vs_prim.v_uint32() # number of local symbols
|
||||||
|
self.iextrel = vs_prim.v_uint32() # index into external relocation entries
|
||||||
|
self.nextrel = vs_prim.v_uint32() # number of external relocation entries
|
||||||
|
self.iinit_iterm = vs_prim.v_uint32() # low 16 bits are the index into the init section, high 16 bits are the index into the term section
|
||||||
|
self.ninit_nterm = vs_prim.v_uint32() # low 16 bits are the number of init section entries, high 16 bits are the number of term section entries
|
||||||
|
self.objc_module_info_addr = vs_prim.v_uint32() # the (__OBJC,__module_info) section
|
||||||
|
self.objc_module_info_size = vs_prim.v_uint32() # the (__OBJC,__module_info) section
|
||||||
|
|
||||||
|
|
||||||
|
class dylib_module_64(vstruct.VStruct):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
vstruct.VStruct.__init__(self)
|
||||||
|
self.module_name = vs_prim.v_uint32() # the module name (index into string table)
|
||||||
|
self.iextdefsym = vs_prim.v_uint32() # index into externally defined symbols
|
||||||
|
self.nextdefsym = vs_prim.v_uint32() # number of externally defined symbols
|
||||||
|
self.irefsym = vs_prim.v_uint32() # index into reference symbol table
|
||||||
|
self.nrefsym = vs_prim.v_uint32() # number of reference symbol table entries
|
||||||
|
self.ilocalsym = vs_prim.v_uint32() # index into symbols for local symbols
|
||||||
|
self.nlocalsym = vs_prim.v_uint32() # number of local symbols
|
||||||
|
self.iextrel = vs_prim.v_uint32() # index into external relocation entries
|
||||||
|
self.nextrel = vs_prim.v_uint32() # number of external relocation entries
|
||||||
|
self.iinit_iterm = vs_prim.v_uint32() # low 16 bits are the index into the init section, high 16 bits are the index into the term section
|
||||||
|
self.ninit_nterm = vs_prim.v_uint32() # low 16 bits are the number of init section entries, high 16 bits are the number of term section entries
|
||||||
|
self.objc_module_info_size = vs_prim.v_uint32() # the (__OBJC,__module_info) section
|
||||||
|
self.objc_module_info_addr = vs_prim.v_uint64() # the (__OBJC,__module_info) section
|
||||||
|
|
||||||
|
|
||||||
|
class dylib_reference(vstruct.VStruct):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
vstruct.VStruct.__init__(self)
|
||||||
|
self.flags = vs_prim.v_uint32() # flags to indicate the type of reference
|
||||||
|
|
||||||
|
|
||||||
|
class twolevel_hints_command(vstruct.VStruct):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
vstruct.VStruct.__init__(self)
|
||||||
|
self.cmd = vs_prim.v_uint32() # LC_TWOLEVEL_HINTS
|
||||||
|
self.cmdsize = vs_prim.v_uint32() # sizeof(struct twolevel_hints_command)
|
||||||
|
self.offset = vs_prim.v_uint32() # offset to the hint table
|
||||||
|
self.nhints = vs_prim.v_uint32() # number of hints in the hint table
|
||||||
|
|
||||||
|
|
||||||
|
class twolevel_hint(vstruct.VStruct):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
vstruct.VStruct.__init__(self)
|
||||||
|
self.itoc = vs_prim.v_uint32() # index into the table of contents
|
||||||
|
|
||||||
|
class prebind_cksum_command(vstruct.VStruct):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
vstruct.VStruct.__init__(self)
|
||||||
|
self.cmd = vs_prim.v_uint32() # LC_PREBIND_CKSUM
|
||||||
|
self.cmdsize = vs_prim.v_uint32() # sizeof(struct prebind_cksum_command)
|
||||||
|
self.cksum = vs_prim.v_uint32() # the check sum or zero
|
||||||
|
|
||||||
|
|
||||||
|
class uuid_command(vstruct.VStruct):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
vstruct.VStruct.__init__(self)
|
||||||
|
self.cmd = vs_prim.v_uint32() # LC_UUID
|
||||||
|
self.cmdsize = vs_prim.v_uint32() # sizeof(struct uuid_command)
|
||||||
|
self.uuid[16] = vs_prim.v_uint8() # the 128-bit uuid
|
||||||
|
|
||||||
|
|
||||||
|
class rpath_command(vstruct.VStruct):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
vstruct.VStruct.__init__(self)
|
||||||
|
self.cmd = vs_prim.v_uint32() # LC_RPATH
|
||||||
|
self.cmdsize = vs_prim.v_uint32() # includes string
|
||||||
|
self.path = lc_str() # path to add to run path
|
||||||
|
|
||||||
|
|
||||||
|
class linkedit_data_command(vstruct.VStruct):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
vstruct.VStruct.__init__(self)
|
||||||
|
self.cmd = vs_prim.v_uint32() # LC_CODE_SIGNATURE or LC_SEGMENT_SPLIT_INFO
|
||||||
|
self.cmdsize = vs_prim.v_uint32() # sizeof(struct linkedit_data_command)
|
||||||
|
self.dataoff = vs_prim.v_uint32() # file offset of data in __LINKEDIT segment
|
||||||
|
self.datasize = vs_prim.v_uint32() # file size of data in __LINKEDIT segment
|
||||||
|
|
||||||
|
|
||||||
|
class encryption_info_command(vstruct.VStruct):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
vstruct.VStruct.__init__(self)
|
||||||
|
self.cmd = vs_prim.v_uint32() # LC_ENCRYPTION_INFO
|
||||||
|
self.cmdsize = vs_prim.v_uint32() # sizeof(struct encryption_info_command)
|
||||||
|
self.cryptoff = vs_prim.v_uint32() # file offset of encrypted range
|
||||||
|
self.cryptsize = vs_prim.v_uint32() # file size of encrypted range
|
||||||
|
self.cryptid = vs_prim.v_uint32() # which enryption system, 0 means not-encrypted yet
|
||||||
|
|
||||||
|
|
||||||
|
class symseg_command(vstruct.VStruct):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
vstruct.VStruct.__init__(self)
|
||||||
|
self.cmd = vs_prim.v_uint32() # LC_SYMSEG
|
||||||
|
self.cmdsize = vs_prim.v_uint32() # sizeof(struct symseg_command)
|
||||||
|
self.offset = vs_prim.v_uint32() # symbol segment offset
|
||||||
|
self.size = vs_prim.v_uint32() # symbol segment size in bytes
|
||||||
|
|
||||||
|
|
||||||
|
class ident_command(vstruct.VStruct):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
vstruct.VStruct.__init__(self)
|
||||||
|
self.cmd = vs_prim.v_uint32() # LC_IDENT
|
||||||
|
self.cmdsize = vs_prim.v_uint32() # strings that follow this command
|
||||||
|
|
||||||
|
class fvmfile_command(vstruct.VStruct):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
vstruct.VStruct.__init__(self)
|
||||||
|
self.cmd = vs_prim.v_uint32() # LC_FVMFILE
|
||||||
|
self.cmdsize = vs_prim.v_uint32() # includes pathname string
|
||||||
|
self.name = lc_str() # files pathname
|
||||||
|
self.header_addr = vs_prim.v_uint32() # files virtual address
|
||||||
|
|
|
@ -0,0 +1,218 @@
|
||||||
|
|
||||||
|
import vstruct
|
||||||
|
from vstruct.primitives import *
|
||||||
|
|
||||||
|
class IMAGE_BASE_RELOCATION(vstruct.VStruct):
|
||||||
|
def __init__(self):
|
||||||
|
vstruct.VStruct.__init__(self)
|
||||||
|
self.VirtualAddress = v_uint32()
|
||||||
|
self.SizeOfBlock = v_uint32()
|
||||||
|
|
||||||
|
class IMAGE_DATA_DIRECTORY(vstruct.VStruct):
|
||||||
|
def __init__(self):
|
||||||
|
vstruct.VStruct.__init__(self)
|
||||||
|
self.VirtualAddress = v_uint32()
|
||||||
|
self.Size = v_uint32()
|
||||||
|
|
||||||
|
class IMAGE_DOS_HEADER(vstruct.VStruct):
|
||||||
|
def __init__(self):
|
||||||
|
vstruct.VStruct.__init__(self)
|
||||||
|
self.e_magic = v_uint16()
|
||||||
|
self.e_cblp = v_uint16()
|
||||||
|
self.e_cp = v_uint16()
|
||||||
|
self.e_crlc = v_uint16()
|
||||||
|
self.e_cparhdr = v_uint16()
|
||||||
|
self.e_minalloc = v_uint16()
|
||||||
|
self.e_maxalloc = v_uint16()
|
||||||
|
self.e_ss = v_uint16()
|
||||||
|
self.e_sp = v_uint16()
|
||||||
|
self.e_csum = v_uint16()
|
||||||
|
self.e_ip = v_uint16()
|
||||||
|
self.e_cs = v_uint16()
|
||||||
|
self.e_lfarlc = v_uint16()
|
||||||
|
self.e_ovno = v_uint16()
|
||||||
|
self.e_res = vstruct.VArray([v_uint16() for i in range(4)])
|
||||||
|
self.e_oemid = v_uint16()
|
||||||
|
self.e_oeminfo = v_uint16()
|
||||||
|
self.e_res2 = vstruct.VArray([v_uint16() for i in range(10)])
|
||||||
|
self.e_lfanew = v_uint32()
|
||||||
|
|
||||||
|
class IMAGE_EXPORT_DIRECTORY(vstruct.VStruct):
|
||||||
|
def __init__(self):
|
||||||
|
vstruct.VStruct.__init__(self)
|
||||||
|
self.Characteristics = v_uint32()
|
||||||
|
self.TimeDateStamp = v_uint32()
|
||||||
|
self.MajorVersion = v_uint16()
|
||||||
|
self.MinorVersion = v_uint16()
|
||||||
|
self.Name = v_uint32()
|
||||||
|
self.Base = v_uint32()
|
||||||
|
self.NumberOfFunctions = v_uint32()
|
||||||
|
self.NumberOfNames = v_uint32()
|
||||||
|
self.AddressOfFunctions = v_uint32()
|
||||||
|
self.AddressOfNames = v_uint32()
|
||||||
|
self.AddressOfOrdinals = v_uint32()
|
||||||
|
|
||||||
|
class IMAGE_FILE_HEADER(vstruct.VStruct):
|
||||||
|
def __init__(self):
|
||||||
|
vstruct.VStruct.__init__(self)
|
||||||
|
self.Machine = v_uint16()
|
||||||
|
self.NumberOfSections = v_uint16()
|
||||||
|
self.TimeDateStamp = v_uint32()
|
||||||
|
self.PointerToSymbolTable = v_uint32()
|
||||||
|
self.NumberOfSymbols = v_uint32()
|
||||||
|
self.SizeOfOptionalHeader = v_uint16()
|
||||||
|
self.Ccharacteristics = v_uint16()
|
||||||
|
|
||||||
|
class IMAGE_IMPORT_DIRECTORY(vstruct.VStruct):
|
||||||
|
def __init__(self):
|
||||||
|
vstruct.VStruct.__init__(self)
|
||||||
|
self.OriginalFirstThunk = v_uint32()
|
||||||
|
self.TimeDateStamp = v_uint32()
|
||||||
|
self.ForwarderChain = v_uint32()
|
||||||
|
self.Name = v_uint32()
|
||||||
|
self.FirstThunk = v_uint32()
|
||||||
|
|
||||||
|
class IMAGE_LOAD_CONFIG_DIRECTORY(vstruct.VStruct):
|
||||||
|
def __init__(self):
|
||||||
|
vstruct.VStruct.__init__(self)
|
||||||
|
self.Size = v_uint32()
|
||||||
|
self.TimeDateStamp = v_uint32()
|
||||||
|
self.MajorVersion = v_uint16()
|
||||||
|
self.MinorVersion = v_uint16()
|
||||||
|
self.GlobalFlagsClear = v_uint32()
|
||||||
|
self.GlobalFlagsSet = v_uint32()
|
||||||
|
self.CriticalSectionDefaultTimeout = v_uint32()
|
||||||
|
self.DeCommitFreeBlockThreshold = v_uint32()
|
||||||
|
self.DeCommitTotalFreeThreshold = v_uint32()
|
||||||
|
self.LockPrefixTable = v_uint32()
|
||||||
|
self.MaximumAllocationSize = v_uint32()
|
||||||
|
self.VirtualMemoryThreshold = v_uint32()
|
||||||
|
self.ProcessHeapFlags = v_uint32()
|
||||||
|
self.ProcessAffinityMask = v_uint32()
|
||||||
|
self.CSDVersion = v_uint16()
|
||||||
|
self.Reserved1 = v_uint16()
|
||||||
|
self.EditList = v_uint32()
|
||||||
|
self.SecurityCookie = v_uint32()
|
||||||
|
self.SEHandlerTable = v_uint32()
|
||||||
|
self.SEHandlerCount = v_uint32()
|
||||||
|
|
||||||
|
class IMAGE_NT_HEADERS(vstruct.VStruct):
|
||||||
|
def __init__(self):
|
||||||
|
vstruct.VStruct.__init__(self)
|
||||||
|
self.Signature = v_bytes(4)
|
||||||
|
self.FileHeader = IMAGE_FILE_HEADER()
|
||||||
|
self.OptionalHeader = IMAGE_OPTIONAL_HEADER()
|
||||||
|
|
||||||
|
class IMAGE_NT_HEADERS64(vstruct.VStruct):
|
||||||
|
def __init__(self):
|
||||||
|
vstruct.VStruct.__init__(self)
|
||||||
|
self.Signature = v_bytes(4)
|
||||||
|
self.FileHeader = IMAGE_FILE_HEADER()
|
||||||
|
self.OptionalHeader = IMAGE_OPTIONAL_HEADER64()
|
||||||
|
|
||||||
|
class IMAGE_OPTIONAL_HEADER(vstruct.VStruct):
|
||||||
|
def __init__(self):
|
||||||
|
vstruct.VStruct.__init__(self)
|
||||||
|
self.Magic = v_bytes(2)
|
||||||
|
self.MajorLinkerVersion = v_uint8()
|
||||||
|
self.MinorLinkerVersion = v_uint8()
|
||||||
|
self.SizeOfCode = v_uint32()
|
||||||
|
self.SizeOfInitializedData = v_uint32()
|
||||||
|
self.SizeOfUninitializedData = v_uint32()
|
||||||
|
self.AddressOfEntryPoint = v_uint32()
|
||||||
|
self.BaseOfCode = v_uint32()
|
||||||
|
self.BaseOfData = v_uint32()
|
||||||
|
self.ImageBase = v_uint32()
|
||||||
|
self.SectionAlignment = v_uint32()
|
||||||
|
self.FileAlignment = v_uint32()
|
||||||
|
self.MajorOperatingSystemVersion = v_uint16()
|
||||||
|
self.MinorOperatingSystemVersion = v_uint16()
|
||||||
|
self.MajorImageVersion = v_uint16()
|
||||||
|
self.MinorImageVersion = v_uint16()
|
||||||
|
self.MajorSubsystemVersion = v_uint16()
|
||||||
|
self.MinorSubsystemVersion = v_uint16()
|
||||||
|
self.Win32VersionValue = v_uint32()
|
||||||
|
self.SizeOfImage = v_uint32()
|
||||||
|
self.SizeOfHeaders = v_uint32()
|
||||||
|
self.CheckSum = v_uint32()
|
||||||
|
self.Subsystem = v_uint16()
|
||||||
|
self.DllCharacteristics = v_uint16()
|
||||||
|
self.SizeOfStackReserve = v_uint32()
|
||||||
|
self.SizeOfStackCommit = v_uint32()
|
||||||
|
self.SizeOfHeapReserve = v_uint32()
|
||||||
|
self.SizeOfHeapCommit = v_uint32()
|
||||||
|
self.LoaderFlags = v_uint32()
|
||||||
|
self.NumberOfRvaAndSizes = v_uint32()
|
||||||
|
self.DataDirectory = vstruct.VArray([IMAGE_DATA_DIRECTORY() for i in range(16)])
|
||||||
|
|
||||||
|
class IMAGE_OPTIONAL_HEADER64(vstruct.VStruct):
|
||||||
|
def __init__(self):
|
||||||
|
vstruct.VStruct.__init__(self)
|
||||||
|
self.Magic = v_bytes(2)
|
||||||
|
self.MajorLinkerVersion = v_uint8()
|
||||||
|
self.MinorLinkerVersion = v_uint8()
|
||||||
|
self.SizeOfCode = v_uint32()
|
||||||
|
self.SizeOfInitializedData = v_uint32()
|
||||||
|
self.SizeOfUninitializedData = v_uint32()
|
||||||
|
self.AddressOfEntryPoint = v_uint32()
|
||||||
|
self.BaseOfCode = v_uint32()
|
||||||
|
self.ImageBase = v_uint64()
|
||||||
|
self.SectionAlignment = v_uint32()
|
||||||
|
self.FileAlignment = v_uint32()
|
||||||
|
self.MajorOperatingSystemVersion = v_uint16()
|
||||||
|
self.MinorOperatingSystemVersion = v_uint16()
|
||||||
|
self.MajorImageVersion = v_uint16()
|
||||||
|
self.MinorImageVersion = v_uint16()
|
||||||
|
self.MajorSubsystemVersion = v_uint16()
|
||||||
|
self.MinorSubsystemVersion = v_uint16()
|
||||||
|
self.Win32VersionValue = v_uint32()
|
||||||
|
self.SizeOfImage = v_uint32()
|
||||||
|
self.SizeOfHeaders = v_uint32()
|
||||||
|
self.CheckSum = v_uint32()
|
||||||
|
self.Subsystem = v_uint16()
|
||||||
|
self.DllCharacteristics = v_uint16()
|
||||||
|
self.SizeOfStackReserve = v_uint64()
|
||||||
|
self.SizeOfStackCommit = v_uint64()
|
||||||
|
self.SizeOfHeapReserve = v_uint64()
|
||||||
|
self.SizeOfHeapCommit = v_uint64()
|
||||||
|
self.LoaderFlags = v_uint32()
|
||||||
|
self.NumberOfRvaAndSizes = v_uint32()
|
||||||
|
self.DataDirectory = vstruct.VArray([IMAGE_DATA_DIRECTORY() for i in range(16)])
|
||||||
|
|
||||||
|
class IMAGE_RESOURCE_DIRECTORY(vstruct.VStruct):
|
||||||
|
def __init__(self):
|
||||||
|
vstruct.VStruct.__init__(self)
|
||||||
|
self.Characteristics = v_uint32()
|
||||||
|
self.TimeDateStamp = v_uint32()
|
||||||
|
self.MajorVersion = v_uint16()
|
||||||
|
self.MinorVersion = v_uint16()
|
||||||
|
self.NumberOfNamedEntries = v_uint16()
|
||||||
|
self.NumberOfIdEntries = v_uint16()
|
||||||
|
|
||||||
|
class IMAGE_SECTION_HEADER(vstruct.VStruct):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
vstruct.VStruct.__init__(self)
|
||||||
|
self.Name = v_str(8)
|
||||||
|
self.VirtualSize = v_uint32()
|
||||||
|
self.VirtualAddress = v_uint32()
|
||||||
|
self.SizeOfRawData = v_uint32()
|
||||||
|
self.PointerToRawData = v_uint32()
|
||||||
|
self.PointerToRelocations = v_uint32()
|
||||||
|
self.PointerToLineNumbers = v_uint32()
|
||||||
|
self.NumberOfRelocations = v_uint16()
|
||||||
|
self.NumberOfLineNumbers = v_uint16()
|
||||||
|
self.Characteristics = v_uint32()
|
||||||
|
|
||||||
|
|
||||||
|
class IMAGE_RUNTIME_FUNCTION_ENTRY(vstruct.VStruct):
|
||||||
|
"""
|
||||||
|
Used in the .pdata section of a PE32+ for all non
|
||||||
|
leaf functions.
|
||||||
|
"""
|
||||||
|
def __init__(self):
|
||||||
|
vstruct.VStruct.__init__(self)
|
||||||
|
self.BeginAddress = v_uint32()
|
||||||
|
self.EndAddress = v_uint32()
|
||||||
|
self.UnwindInfoAddress = v_uint32()
|
||||||
|
|
|
@ -0,0 +1,231 @@
|
||||||
|
|
||||||
|
# FIXME this is named wrong!
|
||||||
|
|
||||||
|
import vstruct
|
||||||
|
from vstruct.primitives import *
|
||||||
|
|
||||||
|
class CLIENT_ID(vstruct.VStruct):
|
||||||
|
def __init__(self):
|
||||||
|
vstruct.VStruct.__init__(self)
|
||||||
|
self.UniqueProcess = v_ptr()
|
||||||
|
self.UniqueThread = v_ptr()
|
||||||
|
|
||||||
|
class EXCEPTION_RECORD(vstruct.VStruct):
|
||||||
|
def __init__(self):
|
||||||
|
vstruct.VStruct.__init__(self)
|
||||||
|
self.ExceptionCode = v_uint32()
|
||||||
|
self.ExceptionFlags = v_uint32()
|
||||||
|
self.ExceptionRecord = v_ptr()
|
||||||
|
self.ExceptionAddress = v_ptr()
|
||||||
|
self.NumberParameters = v_uint32()
|
||||||
|
|
||||||
|
class EXCEPTION_REGISTRATION(vstruct.VStruct):
|
||||||
|
def __init__(self):
|
||||||
|
vstruct.VStruct.__init__(self)
|
||||||
|
self.prev = v_ptr()
|
||||||
|
self.handler = v_ptr()
|
||||||
|
|
||||||
|
class HEAP(vstruct.VStruct):
|
||||||
|
def __init__(self):
|
||||||
|
vstruct.VStruct.__init__(self)
|
||||||
|
self.Entry = HEAP_ENTRY()
|
||||||
|
self.Signature = v_uint32()
|
||||||
|
self.Flags = v_uint32()
|
||||||
|
self.ForceFlags = v_uint32()
|
||||||
|
self.VirtualMemoryThreshold = v_uint32()
|
||||||
|
self.SegmentReserve = v_uint32()
|
||||||
|
self.SegmentCommit = v_uint32()
|
||||||
|
self.DeCommitFreeBlockThreshold = v_uint32()
|
||||||
|
self.DeCommitTotalFreeThreshold = v_uint32()
|
||||||
|
self.TotalFreeSize = v_uint32()
|
||||||
|
self.MaximumAllocationSize = v_uint32()
|
||||||
|
self.ProcessHeapsListIndex = v_uint16()
|
||||||
|
self.HeaderValidateLength = v_uint16()
|
||||||
|
self.HeaderValidateCopy = v_ptr()
|
||||||
|
self.NextAvailableTagIndex = v_uint16()
|
||||||
|
self.MaximumTagIndex = v_uint16()
|
||||||
|
self.TagEntries = v_ptr()
|
||||||
|
self.UCRSegments = v_ptr()
|
||||||
|
self.UnusedUnCommittedRanges = v_ptr()
|
||||||
|
self.AlignRound = v_uint32()
|
||||||
|
self.AlignMask = v_uint32()
|
||||||
|
self.VirtualAllocBlocks = ListEntry()
|
||||||
|
self.Segments = vstruct.VArray([v_uint32() for i in range(64)])
|
||||||
|
self.u = vstruct.VArray([v_uint8() for i in range(16)])
|
||||||
|
self.u2 = vstruct.VArray([v_uint8() for i in range(2)])
|
||||||
|
self.AllocatorBackTraceIndex = v_uint16()
|
||||||
|
self.NonDedicatedListLength = v_uint32()
|
||||||
|
self.LargeBlocksIndex = v_ptr()
|
||||||
|
self.PseudoTagEntries = v_ptr()
|
||||||
|
self.FreeLists = vstruct.VArray([ListEntry() for i in range(128)])
|
||||||
|
self.LockVariable = v_uint32()
|
||||||
|
self.CommitRoutine = v_ptr()
|
||||||
|
self.FrontEndHeap = v_ptr()
|
||||||
|
self.FrontEndHeapLockCount = v_uint16()
|
||||||
|
self.FrontEndHeapType = v_uint8()
|
||||||
|
self.LastSegmentIndex = v_uint8()
|
||||||
|
|
||||||
|
class HEAP_SEGMENT(vstruct.VStruct):
|
||||||
|
def __init__(self):
|
||||||
|
vstruct.VStruct.__init__(self)
|
||||||
|
self.Entry = HEAP_ENTRY()
|
||||||
|
self.SegmentSignature = v_uint32()
|
||||||
|
self.SegmentFlags = v_uint32()
|
||||||
|
self.Heap = v_ptr()
|
||||||
|
self.LargestUncommitedRange = v_uint32()
|
||||||
|
self.BaseAddress = v_ptr()
|
||||||
|
self.NumberOfPages = v_uint32()
|
||||||
|
self.FirstEntry = v_ptr()
|
||||||
|
self.LastValidEntry = v_ptr()
|
||||||
|
self.NumberOfUnCommittedPages = v_uint32()
|
||||||
|
self.NumberOfUnCommittedRanges = v_uint32()
|
||||||
|
self.UncommittedRanges = v_ptr()
|
||||||
|
self.SegmentAllocatorBackTraceIndex = v_uint16()
|
||||||
|
self.Reserved = v_uint16()
|
||||||
|
self.LastEntryInSegment = v_ptr()
|
||||||
|
|
||||||
|
class HEAP_ENTRY(vstruct.VStruct):
|
||||||
|
def __init__(self):
|
||||||
|
vstruct.VStruct.__init__(self)
|
||||||
|
self.Size = v_uint16()
|
||||||
|
self.PrevSize = v_uint16()
|
||||||
|
self.SegmentIndex = v_uint8()
|
||||||
|
self.Flags = v_uint8()
|
||||||
|
self.Unused = v_uint8()
|
||||||
|
self.TagIndex = v_uint8()
|
||||||
|
|
||||||
|
class ListEntry(vstruct.VStruct):
|
||||||
|
def __init__(self):
|
||||||
|
vstruct.VStruct.__init__(self)
|
||||||
|
self.Flink = v_ptr()
|
||||||
|
self.Blink = v_ptr()
|
||||||
|
|
||||||
|
class NT_TIB(vstruct.VStruct):
|
||||||
|
def __init__(self):
|
||||||
|
vstruct.VStruct.__init__(self)
|
||||||
|
self.ExceptionList = v_ptr()
|
||||||
|
self.StackBase = v_ptr()
|
||||||
|
self.StackLimit = v_ptr()
|
||||||
|
self.SubSystemTib = v_ptr()
|
||||||
|
self.FiberData = v_ptr()
|
||||||
|
#x.Version = v_ptr() # This is a union field
|
||||||
|
self.ArbitraryUserPtr = v_ptr()
|
||||||
|
self.Self = v_ptr()
|
||||||
|
|
||||||
|
class PEB(vstruct.VStruct):
|
||||||
|
def __init__(self):
|
||||||
|
vstruct.VStruct.__init__(self)
|
||||||
|
self.InheritedAddressSpace = v_uint8()
|
||||||
|
self.ReadImageFileExecOptions = v_uint8()
|
||||||
|
self.BeingDebugged = v_uint8()
|
||||||
|
self.SpareBool = v_uint8()
|
||||||
|
self.Mutant = v_ptr()
|
||||||
|
self.ImageBaseAddress = v_ptr()
|
||||||
|
self.Ldr = v_ptr()
|
||||||
|
self.ProcessParameters = v_ptr()
|
||||||
|
self.SubSystemData = v_ptr()
|
||||||
|
self.ProcessHeap = v_ptr()
|
||||||
|
self.FastPebLock = v_ptr()
|
||||||
|
self.FastPebLockRoutine = v_ptr()
|
||||||
|
self.FastPebUnlockRoutine = v_ptr()
|
||||||
|
self.EnvironmentUpdateCount = v_uint32()
|
||||||
|
self.KernelCallbackTable = v_ptr()
|
||||||
|
self.SystemReserved = v_uint32()
|
||||||
|
self.AtlThunkSListPtr32 = v_ptr()
|
||||||
|
self.FreeList = v_ptr()
|
||||||
|
self.TlsExpansionCounter = v_uint32()
|
||||||
|
self.TlsBitmap = v_ptr()
|
||||||
|
self.TlsBitmapBits = vstruct.VArray([v_uint32() for i in range(2)])
|
||||||
|
self.ReadOnlySharedMemoryBase = v_ptr()
|
||||||
|
self.ReadOnlySharedMemoryHeap = v_ptr()
|
||||||
|
self.ReadOnlyStaticServerData = v_ptr()
|
||||||
|
self.AnsiCodePageData = v_ptr()
|
||||||
|
self.OemCodePageData = v_ptr()
|
||||||
|
self.UnicodeCaseTableData = v_ptr()
|
||||||
|
self.NumberOfProcessors = v_uint32()
|
||||||
|
self.NtGlobalFlag = v_uint64()
|
||||||
|
self.CriticalSectionTimeout = v_uint64()
|
||||||
|
self.HeapSegmentReserve = v_uint32()
|
||||||
|
self.HeapSegmentCommit = v_uint32()
|
||||||
|
self.HeapDeCommitTotalFreeThreshold = v_uint32()
|
||||||
|
self.HeapDeCommitFreeBlockThreshold = v_uint32()
|
||||||
|
self.NumberOfHeaps = v_uint32()
|
||||||
|
self.MaximumNumberOfHeaps = v_uint32()
|
||||||
|
self.ProcessHeaps = v_ptr()
|
||||||
|
self.GdiSharedHandleTable = v_ptr()
|
||||||
|
self.ProcessStarterHelper = v_ptr()
|
||||||
|
self.GdiDCAttributeList = v_uint32()
|
||||||
|
self.LoaderLock = v_ptr()
|
||||||
|
self.OSMajorVersion = v_uint32()
|
||||||
|
self.OSMinorVersion = v_uint32()
|
||||||
|
self.OSBuildNumber = v_uint16()
|
||||||
|
self.OSCSDVersion = v_uint16()
|
||||||
|
self.OSPlatformId = v_uint32()
|
||||||
|
self.ImageSubsystem = v_uint32()
|
||||||
|
self.ImageSubsystemMajorVersion = v_uint32()
|
||||||
|
self.ImageSubsystemMinorVersion = v_uint32()
|
||||||
|
self.ImageProcessAffinityMask = v_uint32()
|
||||||
|
self.GdiHandleBuffer = vstruct.VArray([v_ptr() for i in range(34)])
|
||||||
|
self.PostProcessInitRoutine = v_ptr()
|
||||||
|
self.TlsExpansionBitmap = v_ptr()
|
||||||
|
self.TlsExpansionBitmapBits = vstruct.VArray([v_uint32() for i in range(32)])
|
||||||
|
self.SessionId = v_uint32()
|
||||||
|
self.AppCompatFlags = v_uint64()
|
||||||
|
self.AppCompatFlagsUser = v_uint64()
|
||||||
|
self.pShimData = v_ptr()
|
||||||
|
self.AppCompatInfo = v_ptr()
|
||||||
|
self.CSDVersion = v_ptr()
|
||||||
|
self.UNKNOWN = v_uint32()
|
||||||
|
self.ActivationContextData = v_ptr()
|
||||||
|
self.ProcessAssemblyStorageMap = v_ptr()
|
||||||
|
self.SystemDefaultActivationContextData = v_ptr()
|
||||||
|
self.SystemAssemblyStorageMap = v_ptr()
|
||||||
|
self.MinimumStackCommit = v_uint32()
|
||||||
|
|
||||||
|
class SEH3_SCOPETABLE(vstruct.VStruct):
|
||||||
|
def __init__(self):
|
||||||
|
vstruct.VStruct.__init__(self)
|
||||||
|
self.EnclosingLevel = v_int32()
|
||||||
|
self.FilterFunction = v_ptr()
|
||||||
|
self.HandlerFunction = v_ptr()
|
||||||
|
|
||||||
|
class SEH4_SCOPETABLE(vstruct.VStruct):
|
||||||
|
def __init__(self):
|
||||||
|
vstruct.VStruct.__init__(self)
|
||||||
|
self.GSCookieOffset = v_int32()
|
||||||
|
self.GSCookieXOROffset = v_int32()
|
||||||
|
self.EHCookieOffset = v_int32()
|
||||||
|
self.EHCookieXOROffset = v_int32()
|
||||||
|
self.EnclosingLevel = v_int32()
|
||||||
|
self.FilterFunction = v_ptr()
|
||||||
|
self.HandlerFunction = v_ptr()
|
||||||
|
|
||||||
|
class TEB(vstruct.VStruct):
|
||||||
|
def __init__(self):
|
||||||
|
vstruct.VStruct.__init__(self)
|
||||||
|
self.TIB = NT_TIB()
|
||||||
|
self.EnvironmentPointer = v_ptr()
|
||||||
|
self.ClientId = CLIENT_ID()
|
||||||
|
self.ActiveRpcHandle = v_ptr()
|
||||||
|
self.ThreadLocalStorage = v_ptr()
|
||||||
|
self.ProcessEnvironmentBlock = v_ptr()
|
||||||
|
self.LastErrorValue = v_uint32()
|
||||||
|
self.CountOfOwnedCriticalSections = v_uint32()
|
||||||
|
self.CsrClientThread = v_ptr()
|
||||||
|
self.Win32ThreadInfo = v_ptr()
|
||||||
|
self.User32Reserved = vstruct.VArray([v_uint32() for i in range(26)])
|
||||||
|
self.UserReserved = vstruct.VArray([v_uint32() for i in range(5)])
|
||||||
|
self.WOW32Reserved = v_ptr()
|
||||||
|
self.CurrentLocale = v_uint32()
|
||||||
|
self.FpSoftwareStatusRegister = v_uint32()
|
||||||
|
|
||||||
|
class CLSID(vstruct.VStruct):
|
||||||
|
def __init__(self):
|
||||||
|
vstruct.VStruct.__init__(self)
|
||||||
|
self.uuid = GUID()
|
||||||
|
|
||||||
|
class IID(vstruct.VStruct):
|
||||||
|
def __init__(self):
|
||||||
|
vstruct.VStruct.__init__(self)
|
||||||
|
self.uuid = GUID()
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
'''
|
||||||
|
The pre-made windows structure defs (extracted from pdb syms)
|
||||||
|
'''
|
||||||
|
|
||||||
|
import envi
|
||||||
|
import ctypes
|
||||||
|
import platform
|
||||||
|
|
||||||
|
def isSysWow64():
|
||||||
|
k32 = ctypes.windll.kernel32
|
||||||
|
if not hasattr(k32, 'IsWow64Process'):
|
||||||
|
return False
|
||||||
|
ret = ctypes.c_ulong(0)
|
||||||
|
myproc = ctypes.c_size_t(-1)
|
||||||
|
if not k32.IsWow64Process(myproc, ctypes.addressof(ret)):
|
||||||
|
return False
|
||||||
|
return bool(ret.value)
|
||||||
|
|
||||||
|
def getCurrentDef(normname):
|
||||||
|
bname, wver, stuff, whichkern = platform.win32_ver()
|
||||||
|
wvertup = wver.split('.')
|
||||||
|
arch = envi.getCurrentArch()
|
||||||
|
if isSysWow64():
|
||||||
|
arch = 'wow64'
|
||||||
|
|
||||||
|
modname = 'vstruct.defs.windows.win_%s_%s_%s.%s' % (wvertup[0], wvertup[1], arch, normname)
|
||||||
|
|
||||||
|
try:
|
||||||
|
mod = __import__(modname, {}, {}, 1)
|
||||||
|
except ImportError, e:
|
||||||
|
mod = None
|
||||||
|
return mod
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
print getCurrentDef('ntdll')
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1 @@
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,354 @@
|
||||||
|
|
||||||
|
import struct
|
||||||
|
|
||||||
|
class v_enum: pass
|
||||||
|
|
||||||
|
class v_base(object):
|
||||||
|
def __init__(self):
|
||||||
|
self._vs_meta = {}
|
||||||
|
|
||||||
|
def vsGetMeta(self, name, defval=None):
|
||||||
|
return self._vs_meta.get(name, defval)
|
||||||
|
|
||||||
|
def vsSetMeta(self, name, value):
|
||||||
|
self._vs_meta[name] = value
|
||||||
|
|
||||||
|
# Sub-classes (primitive base, or VStruct must have these
|
||||||
|
def vsParse(self, bytes): return NotImplemented
|
||||||
|
def vsGetFormat(self): return NotImplemented
|
||||||
|
def vsIsPrim(self): return NotImplemented
|
||||||
|
def vsGetTypeName(self): return NotImplemented
|
||||||
|
|
||||||
|
class v_prim(v_base):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
v_base.__init__(self)
|
||||||
|
# Used by base len(),vsGetFormat, etc...
|
||||||
|
self._vs_value = None
|
||||||
|
self._vs_length = None
|
||||||
|
self._vs_fmt = None
|
||||||
|
|
||||||
|
def vsIsPrim(self):
|
||||||
|
return True
|
||||||
|
|
||||||
|
def vsGetTypeName(self):
|
||||||
|
return self.__class__.__name__
|
||||||
|
|
||||||
|
def vsParse(self, bytes):
|
||||||
|
"""
|
||||||
|
Parser for primitives which assumes we are
|
||||||
|
calling parse directly.
|
||||||
|
"""
|
||||||
|
fmt = "<%s" % self.vsGetFormat()
|
||||||
|
val = struct.unpack(fmt, bytes)[0]
|
||||||
|
self.vsSetParsedValue(val)
|
||||||
|
|
||||||
|
def vsSetParsedValue(self, value):
|
||||||
|
"""
|
||||||
|
Primitives will be assigned their values by a parser
|
||||||
|
which chops data up with struct format strings. This
|
||||||
|
method will be called by parsers to assign the value
|
||||||
|
of a primitive from a struct.unpack call.
|
||||||
|
"""
|
||||||
|
self._vs_value = value
|
||||||
|
|
||||||
|
def vsGetFmtValue(self):
|
||||||
|
"""
|
||||||
|
The emit function uses this to ask each primitive for the
|
||||||
|
object to be put into the struct pack sequence.
|
||||||
|
Most objects just return their value...
|
||||||
|
"""
|
||||||
|
return self._vs_value
|
||||||
|
|
||||||
|
def vsGetValue(self):
|
||||||
|
"""
|
||||||
|
Get the type specific value for this field.
|
||||||
|
(Used by the structure dereference method to return
|
||||||
|
a python native for the field by name)
|
||||||
|
"""
|
||||||
|
return self._vs_value
|
||||||
|
|
||||||
|
def vsSetValue(self, value):
|
||||||
|
"""
|
||||||
|
Set the type specific value for this field.
|
||||||
|
"""
|
||||||
|
self._vs_value = value
|
||||||
|
|
||||||
|
def vsGetFormat(self):
|
||||||
|
return self._vs_fmt
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return repr(self.vsGetValue())
|
||||||
|
|
||||||
|
def __len__(self):
|
||||||
|
return self._vs_length
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return str(self.vsGetValue())
|
||||||
|
|
||||||
|
class v_number(v_prim):
|
||||||
|
|
||||||
|
def __init__(self, value=0, swapend=False):
|
||||||
|
v_prim.__init__(self)
|
||||||
|
self._vs_swapend = swapend
|
||||||
|
self._vs_length = struct.calcsize(self.vsGetFormat())
|
||||||
|
self.vsSetValue(value)
|
||||||
|
|
||||||
|
def vsSetValue(self, value):
|
||||||
|
"""
|
||||||
|
Assure that the value is long() able for all numeric types.
|
||||||
|
"""
|
||||||
|
self._vs_value = long(value)
|
||||||
|
|
||||||
|
def vsSetParsedValue(self, value):
|
||||||
|
# We were parsed N endian. Switch if needed.
|
||||||
|
if self._vs_swapend:
|
||||||
|
oval = value
|
||||||
|
value = 0
|
||||||
|
for i in range(self._vs_length):
|
||||||
|
value = value << 8
|
||||||
|
value += (oval >> (8*i)) & 0xff
|
||||||
|
self.vsSetValue(value)
|
||||||
|
|
||||||
|
def vsGetFormat(self):
|
||||||
|
return self.__class__._vs_fmt
|
||||||
|
|
||||||
|
def __int__(self):
|
||||||
|
return int(self._vs_value)
|
||||||
|
|
||||||
|
def __long__(self):
|
||||||
|
return long(self._vs_value)
|
||||||
|
|
||||||
|
##################################################################
|
||||||
|
# Implement the number API
|
||||||
|
|
||||||
|
def __add__(self, other): return long(self) + long(other)
|
||||||
|
def __sub__(self, other): return long(self) - long(other)
|
||||||
|
def __mul__(self, other): return long(self) * long(other)
|
||||||
|
def __div__(self, other): return long(self) / long(other)
|
||||||
|
def __floordiv__(self, other): return long(self) // long(other)
|
||||||
|
def __mod__(self, other): return long(self) % long(other)
|
||||||
|
def __divmod__(self, other): return divmod(long(self), long(other))
|
||||||
|
def __pow__(self, other, modulo=None): return pow(long(self), long(other), modulo)
|
||||||
|
def __lshift__(self, other): return long(self) << long(other)
|
||||||
|
def __rshift__(self, other): return long(self) >> long(other)
|
||||||
|
def __and__(self, other): return long(self) & long(other)
|
||||||
|
def __xor__(self, other): return long(self) ^ long(other)
|
||||||
|
def __or__(self, other): return long(self) | long(other)
|
||||||
|
|
||||||
|
# Operator swapped variants
|
||||||
|
def __radd__(self, other): return long(other) + long(self)
|
||||||
|
def __rsub__(self, other): return long(other) - long(self)
|
||||||
|
def __rmul__(self, other): return long(other) * long(self)
|
||||||
|
def __rdiv__(self, other): return long(other) / long(self)
|
||||||
|
def __rfloordiv__(self, other): return long(other) // long(self)
|
||||||
|
def __rmod__(self, other): return long(other) % long(self)
|
||||||
|
def __rdivmod__(self, other): return divmod(long(other), long(self))
|
||||||
|
def __rpow__(self, other, modulo=None): return pow(long(other), long(self), modulo)
|
||||||
|
def __rlshift__(self, other): return long(other) << long(self)
|
||||||
|
def __rrshift__(self, other): return long(other) >> long(self)
|
||||||
|
def __rand__(self, other): return long(other) & long(self)
|
||||||
|
def __rxor__(self, other): return long(other) ^ long(self)
|
||||||
|
def __ror__(self, other): return long(other) | long(self)
|
||||||
|
|
||||||
|
# Inplace variants
|
||||||
|
def __iadd__(self, other): self.vsSetValue(self+other); return self
|
||||||
|
def __isub__(self, other): self.vsSetValue(self - other); return self
|
||||||
|
def __imul__(self, other): self.vsSetValue(self*other); return self
|
||||||
|
def __idiv__(self, other): self.vsSetValue(self/other); return self
|
||||||
|
def __ifloordiv__(self, other): self.vsSetValue(self // other); return self
|
||||||
|
def __imod__(self, other): self.vsSetValue(self % other); return self
|
||||||
|
def __ipow__(self, other, modulo=None): self.vsSetValue(pow(self, other, modulo)); return self
|
||||||
|
def __ilshift__(self, other): self.vsSetValue(self << other); return self
|
||||||
|
def __irshift__(self, other): self.vsSetValue(self >> other); return self
|
||||||
|
def __iand__(self, other): self.vsSetValue(self & other); return self
|
||||||
|
def __ixor__(self, other): self.vsSetValue(self ^ other); return self
|
||||||
|
def __ior__(self, other): self.vsSetValue(self | other); return self
|
||||||
|
|
||||||
|
# operator helpers
|
||||||
|
def __neg__(self): return -(long(self))
|
||||||
|
def __pos__(self): return +(long(self))
|
||||||
|
def __abs__(self): return abs(long(self))
|
||||||
|
def __invert__(self): return ~(long(self))
|
||||||
|
|
||||||
|
# index use helper
|
||||||
|
def __index__(self): return long(self)
|
||||||
|
|
||||||
|
def __coerce__(self, other):
|
||||||
|
try:
|
||||||
|
return long(self),long(other)
|
||||||
|
except Exception, e:
|
||||||
|
return NotImplemented
|
||||||
|
|
||||||
|
# Print helpers
|
||||||
|
def __hex__(self): return hex(long(self))
|
||||||
|
def __oct__(self): return oct(long(self))
|
||||||
|
|
||||||
|
class v_uint8(v_number):
|
||||||
|
_vs_builder = True
|
||||||
|
_vs_fmt = "B"
|
||||||
|
|
||||||
|
class v_uint16(v_number):
|
||||||
|
_vs_builder = True
|
||||||
|
_vs_fmt = "H"
|
||||||
|
|
||||||
|
class v_uint32(v_number):
|
||||||
|
_vs_builder = True
|
||||||
|
_vs_fmt = "L"
|
||||||
|
|
||||||
|
class v_uint64(v_number):
|
||||||
|
_vs_builder = True
|
||||||
|
_vs_fmt = "Q"
|
||||||
|
|
||||||
|
class v_int8(v_number):
|
||||||
|
_vs_builder = True
|
||||||
|
_vs_fmt = "b"
|
||||||
|
|
||||||
|
class v_int16(v_number):
|
||||||
|
_vs_builder = True
|
||||||
|
_vs_fmt = "h"
|
||||||
|
|
||||||
|
class v_int32(v_number):
|
||||||
|
_vs_builder = True
|
||||||
|
_vs_fmt = "l"
|
||||||
|
|
||||||
|
class v_int64(v_number):
|
||||||
|
_vs_builder = True
|
||||||
|
_vs_fmt = "q"
|
||||||
|
|
||||||
|
pointersize = struct.calcsize("P")
|
||||||
|
|
||||||
|
class v_size_t(v_number):
|
||||||
|
_vs_builder = True
|
||||||
|
if pointersize == 4:
|
||||||
|
_vs_fmt = "L"
|
||||||
|
else:
|
||||||
|
_vs_fmt = "Q"
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return "0x%.8x" % self._vs_value
|
||||||
|
|
||||||
|
class v_ptr(v_size_t):
|
||||||
|
pass
|
||||||
|
|
||||||
|
class v_ptr32(v_ptr):
|
||||||
|
_vs_builder = True
|
||||||
|
_vs_fmt = "L"
|
||||||
|
|
||||||
|
class v_ptr64(v_ptr):
|
||||||
|
_vs_builder = True
|
||||||
|
_vs_fmt = "Q"
|
||||||
|
|
||||||
|
class v_bytes(v_prim):
|
||||||
|
|
||||||
|
_vs_builder = True
|
||||||
|
|
||||||
|
def __init__(self, size=0, vbytes=None):
|
||||||
|
v_prim.__init__(self)
|
||||||
|
if vbytes == None:
|
||||||
|
vbytes = '\x00' * size
|
||||||
|
self._vs_length = len(vbytes)
|
||||||
|
self._vs_value = vbytes
|
||||||
|
|
||||||
|
def vsGetFormat(self):
|
||||||
|
return "%ds" % len(self)
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return self._vs_value.encode('hex')
|
||||||
|
|
||||||
|
class v_str(v_prim):
|
||||||
|
'''
|
||||||
|
A string placeholder class which will automagically return
|
||||||
|
up to a null terminator (and will keep it's size by null
|
||||||
|
padding when assigned to)
|
||||||
|
'''
|
||||||
|
|
||||||
|
_vs_builder = True
|
||||||
|
|
||||||
|
def __init__(self, size=4, val=''):
|
||||||
|
v_prim.__init__(self)
|
||||||
|
self._vs_length = size
|
||||||
|
self._vs_value = val.ljust(size, '\x00')
|
||||||
|
|
||||||
|
def vsGetValue(self):
|
||||||
|
val = v_prim.vsGetValue(self)
|
||||||
|
return val.split("\x00")[0]
|
||||||
|
|
||||||
|
def vsSetValue(self, val):
|
||||||
|
realval = val.ljust(len(self), '\x00')
|
||||||
|
v_prim.vsSetValue(self, realval)
|
||||||
|
|
||||||
|
def vsGetFormat(self):
|
||||||
|
return "%ds" % len(self)
|
||||||
|
|
||||||
|
def __len__(self):
|
||||||
|
return len(self._vs_value)
|
||||||
|
|
||||||
|
class v_wstr(v_str):
|
||||||
|
'''
|
||||||
|
Unicode variant of the above string class
|
||||||
|
|
||||||
|
NOTE: the size paramater is in WCHARs!
|
||||||
|
'''
|
||||||
|
|
||||||
|
_vs_builder = True
|
||||||
|
|
||||||
|
def __init__(self, size=4, encode='utf-16le', val=''):
|
||||||
|
v_prim.__init__(self)
|
||||||
|
b = val.ljust(size, '\x00').encode(encode)
|
||||||
|
self._vs_length = len(b)
|
||||||
|
self._vs_value = b
|
||||||
|
self._vs_encode = encode
|
||||||
|
|
||||||
|
def vsGetValue(self):
|
||||||
|
val = v_prim.vsGetValue(self)
|
||||||
|
val = val.decode(self._vs_encode)
|
||||||
|
return val.split("\x00")[0]
|
||||||
|
|
||||||
|
def vsSetValue(self, val):
|
||||||
|
rbytes = val.encode(self._vs_encode)
|
||||||
|
rbytes = rbytes.ljust(len(self), '\x00')
|
||||||
|
v_prim.vsSetValue(self, rbytes)
|
||||||
|
|
||||||
|
def vsGetFormat(self):
|
||||||
|
return "%ds" % len(self)
|
||||||
|
|
||||||
|
def __len__(self):
|
||||||
|
return len(self._vs_value)
|
||||||
|
|
||||||
|
|
||||||
|
class GUID(v_prim):
|
||||||
|
|
||||||
|
_vs_builder = True
|
||||||
|
|
||||||
|
def __init__(self, guidstr=None):
|
||||||
|
"""
|
||||||
|
Construct a new GUID primitive. You may specify a GUID string in the
|
||||||
|
constructor to populate initial values.
|
||||||
|
"""
|
||||||
|
v_prim.__init__(self)
|
||||||
|
self._vs_length = 16
|
||||||
|
self._vs_value = "\x00" * 16
|
||||||
|
self._vs_fmt = "16s"
|
||||||
|
self._guid_fields = (0,0,0,0,0,0,0,0,0,0,0)
|
||||||
|
if guidstr != None:
|
||||||
|
self._parseGuidStr(guidstr)
|
||||||
|
|
||||||
|
def _parseGuidStr(self, gstr):
|
||||||
|
gstr = gstr.replace("{","")
|
||||||
|
gstr = gstr.replace("}","")
|
||||||
|
gstr = gstr.replace("-","")
|
||||||
|
bytes = gstr.decode("hex")
|
||||||
|
# Totally cheating... ;)
|
||||||
|
self._guid_fields = struct.unpack(">LHH8B", bytes)
|
||||||
|
|
||||||
|
def vsSetValue(self, bytes):
|
||||||
|
self._guid_fields = struct.unpack("<LHH8B", bytes)
|
||||||
|
|
||||||
|
def vsGetValue(self):
|
||||||
|
return struck.pack("<LHH8B", *self._guid_fields)
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
base = "{%.8x-%.4x-%.4x-%.2x%.2x-%.2x%.2x%.2x%.2x%.2x%.2x}"
|
||||||
|
return base % self._guid_fields
|
||||||
|
|
Loading…
Reference in New Issue