Pass binary data to os.system call - python

I need to call an executable in a python script and also pass binary data (generated in the same script) to this executable.
I have it working like so:
bin = make_config(data)
open('binaryInfo.bin', 'wb+').write(bin)
os.system("something.exe " + "binaryInfo.bin")
I thought I could avoid creating the binaryInfo.bin file altogether by passing 'bin' straight to the os.system call:
bin = make_config(data)
os.system("something.exe " + bin)
But in this case I get an error:
"Can't convert 'bytes' object to str implicitly"
Does anyone know the correct syntax here? Is this even possible?

Does anyone know the correct syntax here? Is this even possible?
Not like you're doing it. You can't pass arbitrary binary data on the UNIX command line, as each argument is inherently treated as null-terminated, and there's a maximum total length limit which is typically 64KB or less.
With some applications which recognize this convention, you may be able to pipe data on stdin using something like:
pipe = os.popen("something.exe -", "w")
pipe.write(bin)
pipe.close()
If the application doesn't recognize "-" for stdin, though, you will probably have to use a temporary file like you're already doing.

os.system(b"something.exe " + bin)
Should do it.. However, I'm not sure you should be sending binary data through the command line. There might be some sort of limit on character count. Also, does this something.exe actually accept binary data through the command line even?

how bout base64encoding it before sending and decoding on the other end... afaik command line arguments must be ascii range values (although this maynot be true... but I think it is..) ...
another option would be to do it the way you currently are and passing the file ...
or maybe see this Passing binary data as arguments in bash

Related

How to get raw hex values from pcap file?

I've been playing around with scapy and want to read through and analyse every hex byte. So far I've been using scapy simply because I don't know another way currently. Before just writing tools myself to go through the pcap files I was wondering if there was an easy way to do it. Here's what I've done so far.
packets = rdpcap('file.pcap')
tcpPackets = []
for packet in packets:
if packet.haslayer(TCP):
tcpPackets.append(packet)
When I run type(tcpPackets[0]) the type I get is:
<class 'scapy.layers.l2.Ether'>
Then when I try to covert the Ether object into a string it gives me a mix of hex and ascii (as noted by the random parenthesis and brackets).
str(tcpPackets[0])
"b'$\\xa2\\xe1\\xe6\\xee\\x9b(\\xcf\\xe9!\\x14\\x8f\\x08\\x00E\\x00\\x00[:\\xc6#\\x00#\\x06\\x0f\\xb9\\n\\x00\\x01\\x04\\xc6)\\x1e\\xf1\\xc0\\xaf\\x07[\\xc1\\xe1\\xff0y<\\x11\\xe3\\x80\\x18 1(\\xb8\\x00\\x00\\x01\\x01\\x08\\n8!\\xd1\\x888\\xac\\xc2\\x9c\\x10%\\x00\\x06MQIsdp\\x03\\x02\\x00\\x05\\x00\\x17paho/34AAE54A75D839566E'"
I have also tried using hexdump but I can't find a way to parse through it.
I can't find the proper dupe now, but this is just a miss-use/miss-understanding of str(). The original data is in a bytes format, for instance x = b'moo'.
When str() retrieves your bytes string, it will do so by calling the __str__ function of the bytes class/object. That will return a representation of itself. The representation will keep b at the beginning because it's believed to distinguish and make it easier for humans to understand that it's a bytes object, as well as avoid encoding issues I guess (alltho that's speculations).
Same as if you tried accessing tcpPackets[0] from a terminal, it would call __repr__ and show you something like <class 'scapy.layers.l2.Ether'> most likely.
As an example code you can experiment with, try this out:
class YourEther(bytes):
def __str__(self):
return '<Made Up Representation>'
print(YourEther())
Obviously scapy's returns another representation, not just a static string that says "made up representation". But you probably get the idea.
So in the case of <class 'scapy.layers.l2.Ether'> it's __repr__ or __str__ function probably returns b'$\\xa2\\....... instead of just it's default class representation (some correction here might be in place tho as I don't remember/know all the technical namification of the behaviors).
As a workaround, this might fix your issue:
hexlify(str(tcpPackets[0]))
All tho you probably have to account for the prepended b' as well as trailing ' and remove those accordingly. (Note: " won't be added in the beginning or end, those are just a second representation in your console when printing. They're not actually there in terms of data)
Scapy is probably more intended to use tcpPackets[0].dst rather than grabing the raw data. But I've got very little experience with Scapy, but it's an abstraction layer for a reason and it's probably hiding the raw data or it's in the core docs some where which I can't find right now.
More info on the __str__ description: Does python `str()` function call `__str__()` function of a class?
Last note, and that is if you actually want to access the raw data, it seams like you can access it with the Raw class: Raw load found, how to access?
You can put all the bytes of a packet into a numpy array as follows:
for p in tcpPackets:
raw_pack_data = np.frombuffer(p.load, dtype = np.uint8)
# Manipulate the bytes stored in raw_pack_data as you like.
This is fast. In my case, rdpcap takes ~20 times longer than putting all the packets into a big array in a similar for loop for a 1.5GB file.

Why python automatically returns character counts when write file

I recently noticed that when I have the following code:
File = "/dir/to/file"
Content = "abcdefg"
with open(File,"a") as f:
f.write(Content)
I got "7" as an output and it is the count of characters in the variable "Content". I do not recall seeing this (I used ipython notebook before, but this time I did it in the python environment in shell) and wonder if I did something wrong. My python version: Python 3.3.3. Thank you for your help.
As always this behaviour is normal for most .write() implementations, see also I/O Base Classes.
For example io.RawIOBase.write
Write the given bytes-like object, b, to the underlying raw stream, and return the number of bytes written.
or io.TextIOBase.write
Write the string s to the stream and return the number of characters written.
Which IO-class is used depends on (the OS and) the parameters given to open. But as far as I can see all of them return some sort of "characters" or "bytes" written count.

Trying to pass a number of bytes to read() via raw_input

I'm doing some extra credit for "Zed Shaw's Learn Python The Hard Way;" the "extra credit" for exercise 15 tells you to read through pydoc file to find other things I could do files. I was interested in figuring out how to have the terminal print out a certain number of bytes of a text file using "read()". I can hard code in the argument for how many bytes to read, but I hit a wall when trying to prompt the user to define the number of bytes.
Here's the script as I have it so far:
from sys import argv
script, filename = argv
txt = open(filename)
print "Here's 24 bytes of your file %r:" % filename
print txt.read(24)
print """What about an arbitrary, not hard-coded number of bytes? Enter the number
of bytes you want read out of the txt file at this prompt, as an integer:"""
how_far = raw_input("> ")
print txt.read(how_far2) # this format makes sense in my head but obviously isn't the done thing.
terminal spits out the error:
"NameError: name 'how_far2' is not defined"
How do I prompt the user of the script to type in a number of bytes, and have the script read out that number of bytes?
BONUS QUESTIONS:
What is the actual-factual term for what I'm doing trying to do here? Pass a variable to a method? Pass a variable to a function?
Is the number of bytes an argument of read? Is that the correct term?
More generally, what's a good place to get a vocabulary list of python terms? Any other books Stack Overflow would recommend, or some in online documentation somewhere? Really looking for a no assumptions, no prior knowledge, "explain it to me like I'm five" level of granularity... a half hour of web-searching hasn't helped too much. I've not found terminology really collected together into any one place online despite a good amount of effort searching the web.
The error message is because you have used how_far in one place and how_far2 in the other.
You'll also need to convert how_far to an int before passing it to read - using int(how_far) for example
You will find it can be called passing a variable, parameter or argument. These are not Python terms, they are general programming terms
raw_input returns a string. file.read expects an integer -- likely you just need to convert the output from raw_input into an integer before you use it.

snmpset in python

I am using the python to send an snmpset message to an snmp agent. I have the correct OID as I can use it to get data with snmpget. However, it will not set the data. I am sending octets in hex format (two hex values) separated by a colon. I might have to put apostrophes around it, right? Here is the example of the line I am sending
foo = os.popen("snmpset -v 2c -c private 192.1.55.222
.1.2.6.5.4.1.24022.4.27.1.6.4.4 x 00:00:04:cf:00:00:00:00:00:00")
as you can see, I am sending an Octet string with type x.
Can anyone hazard a guess as to how I should pass in the set value of "00:00:04:cf:00:00:00:00:00:00". I know the setvalue is of the right length and type because I have used it in a MIB browser.
A couple of things:
1) there is a native python interface you could use instead of calling a system command. There are in fact multiple choices, including pysnmp (done in python) and Net-SNMP's python module (done in C).
2) The Net-SNMP snmpset command expects straight hex code without any :s in it. So if you remove the :s you may find it'll work.

python: deleting numbers in a file

I need to delete numbers from a text file on windows XP. I am new to python and just installed it for data scrubbing.
I have stored the test file in C:\folder1\test1.txt
The contexts on test1.txt is just 1 line:
This must not b3 delet3d, but the number at the end yes 134411
I want to created a file result1.txt which contains
This must not b3 delet3d, but the number at the end yes
Here is what I tried so far
import os
fin = os.open('C:\folder1\test1.txt','r')
I get the following error:
TypeError: an integer is required.
I am not sure what integer it is expecting.
Can you please let me know how to go about programming to get the result I want. Thanks a lot for your help.
You're using open() in the os module, which takes a numeric file mode. You want instead the builtin open() function. Also, backslashes in strings take on a special meaning in Python; you need to double them up if you really mean backslashes. Try:
fin = open('C:\\folder1\\test1.txt','r')
according to http://docs.python.org/library/os.html#file-descriptor-operations, os.open is looking for 'flag' parameter, made of one or more of these flags which 'r' is not. It also seems to indicate that you probably want to look into using open() rather than os.open()
f = open(r'C:\folder1\test1.txt','r')

Categories