Hexadecimal Memory Address to Assembly - python

I am following a buffer overflow tutorial. I have set up my NOP block, I also set up my shell code, now I need to append the return address to the end of my string. I know my return address is :
0xbfffef40
however I need to write it in the form:
xd0\xce\xff\xff (that's just an example address to show what format I need)
I'm not sure how to carry out the conversion between the two.

You can use struct.pack like this:
import struct
struct.pack('<L', 0xbfffef40)
Check the documentation of struct.pack if you want to change the endianness.

Related

depythonifying 'char', got 'str' for pyobjc

0
Story would be: I was using a hardware which can be automatic controlled by a objc framework, it was already used by many colleagues so I can see it as a "fixed" library. But I would like to use it via Python, so with pyobjc I can already connect to this device, but failed to send data into it.
The objc command in header is like this
(BOOL) executeabcCommand:(NSString*)commandabc
withArgs:(uint32_t)args
withData:(uint8_t*)data
writeLength:(NSUInteger)writeLength
readLength:(NSUInteger)readLength
timeoutMilliseconds:(NSUInteger)timeoutMilliseconds
error:(NSError **) error;
and from my python code, data is an argument which can contain 256bytes of data such
as 0x00, 0x01, 0xFF. My python code looks like this:
senddata=Device.alloc().initWithCommunicationInterface_(tcpInterface)
command = 'ABCw'
args= 0x00
writelength = 0x100
readlength = 0x100
data = '\x50\x40'
timeout = 500
success, error = senddata.executeabcCommand_withArgs_withData_writeLength_readLength_timeoutMilliseconds_error_(command, args, data, writelength, readlength, timeout, None)
Whatever I sent into it, it always showing that.
ValueError: depythonifying 'char', got 'str'
I tired to dig in a little bit, but failed to find anything about convert string or list to char with pyobjc
Objective-C follows the rules that apply to C.
So in objc as well as C when we look at uint8_t*, it is in fact the very same as char* in memory. string differs from this only in that sense that it is agreed that the last character ends in \0 to indicate that the char* block that we call string has its cap. So char* blocks end with \0 because, well its a string.
What do we do in C to find out the length of a character block?
We iterate the whole block until we find \0. Usually with a while loop, and break the loop when you find it, your counter inside the loop tells you your length if you did not give it somehow anyway.
It is up to you to interpret the data in the desired format.
Which is why sometime it is easier to cast from void* or to take indeed a char* block which is then cast to and declared as uint8_t data inside the function which makes use if it. Thats the nice part of C to be able to define that as you wish, use that force that was given to you.
So to make your life easier, you could define a length parameter like so
-withData:(uint8_t*)data andLength:(uint64_t)len; to avoid parsing the character stream again, as you know already it is/or should be 256 characters long. The only thing you want to avoid at all cost in C is reading attempts at indices that are out of bound throwing an BAD_ACCESS exception.
But this basic information should enable you to find a way to declare your char* block containing uint8_t data addressed with the very first pointer (*) which also contains the first uint8_t character of the block as str with a specific length or up to the first appearance of \0.
Sidenote:
objective-c #"someNSString" == pythons u"pythonstring"
PS: in your question is not clear who throw that error msg.
Python? Because it could not interpret the data when receiving?
Pyobjc? Because it is python syntax hell when you mix with objc?
The objc runtime? Because it follows the strict rules of C as well?
Python has always been very forgiving about shoe-horning one type into another, but python3 uses Unicode strings by default, which need to be converted into binary strings before plugging into pyobjc methods.
Try specifying the strings as byte objects as b'this'
I was hitting the same error trying to use IOKit:
import objc
from Foundation import NSBundle
IOKit = NSBundle.bundleWithIdentifier_('com.apple.framework.IOKit')
functions = [("IOServiceGetMatchingService", b"II#"), ("IOServiceMatching", b"#*"),]
objc.loadBundleFunctions(IOKit, globals(), functions)
The problem arose when I tried to call the function like so:
IOServiceMatching('AppleSmartBattery')
Receiving
Traceback (most recent call last):
File "<pyshell#53>", line 1, in <module>
IOServiceMatching('AppleSmartBattery')
ValueError: depythonifying 'charptr', got 'str'
While as a byte object I get:
IOServiceMatching(b'AppleSmartBattery')
{
IOProviderClass = AppleSmartBattery;
}

Converting an IP Address string to exactly 4 bytes in Python

So this is very simple, but I'm having trouble getting this to work. I want to, for example, if the incoming IP address string is '168.108.114.22', convert this to a bytes object like:
\xA8\x6C\x72\x16
Basically each part of the IP address is converted to it's hexadecimal equivalent.
I've tried so many ways but couldn't get what I want. String manipulation, using socket.inet_aton, packing, etc. I want to be able to send these bytes over a socket and then receive and parse them at the other end, but I am having trouble just getting my bytes object created and looking like that.
Python's inet_aton function should do what you need, it does return a string containing exactly 4 bytes:
import socket
print socket.inet_aton('168.108.114.22')
print socket.inet_aton('65.66.67.68')
These would display:
¨lr
ABCD
And to convert the four characters back again using inet_ntoa:
print socket.inet_ntoa('\xA8\x6C\x72\x16')
print socket.inet_ntoa('ABCD')
Giving:
65.66.67.68
this
ip='168.108.114.22'
b_out = bytes(map(int,ip.split('.')))
print(b_out)
on python 3 produces
b'\xa8lr\x16'
which should be what you are looking for, if I understand correctly.
Note: there are more specific and optimized utility functions to manipulate IP addresses

How do I make Python 3.4 c_char_array read strings as two bytes?

I'm using pypyodbc with Python 3.4 on Ubuntu 12.04.
I'm trying to get the column names, but something is a little wonky. What is coming back is just the first character as a byte, like this:
(Pdb) Cname.value
b'T'
The thing behind the scenes is a ctypes char array:
(Pdb) Cname
<ctypes.c_char_Array_1024 object at 0xb6a1ad1c>
But if I look at the raw value:
(Pdb) Cname.raw
b'T\x00Y\x00P\x00E\x00_\x00N\x00A\x00M\x00E\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
you can see that the value TYPE_NAME is separated by \x00.
So it appears to me that what's happening is something (ctypes?) is reading that first \x00 as the null terminator for the string instead of part of the characters.
What can I do to modify the way ctypes is being used so that it will read the entire string? Everything else seems to work fine, it's just the descriptions that are wonky.
Your string is encoded in UTF-16LE. You want to call something like Cname.raw.decode('utf_16le').rstrip('\x00'). That will return a Python string, which you can then do with as you please.

How to decode a variable string from C?

Trying to program an UDP connection. The client is in python and the server is in C.
In my python code I defined my PDU as a struct (using the struct module) in this format: 'B 5s 50s' (unsigned char, char[5], char[50]). The issue is that if the strings are not filled, the remainder is garbage, which I should remove.
After unpacking the response from server, if I do:
str = str_from_c.split('\0',1)
It returns me this:
['useful data', '\x00\x01\x00\x00\x00r\x00\x00\x00\xae\xf2d\xb7\x18\x00\x00\x00\x02\x00\x00\x00\x0f\x00\x00\x00\x94\xecd\xb7\xa8\xe6\xb0\t\x00\x00\x00\x00\x00\xa9]\xb7\xca\xf1d\xb7']
How I can dispose the second part?
By despise do you mean dispose? If you just want the text, then only take that from the result - note we're not calling the variable str here as that will shadow the builtin str:
text, rest = str_from_c.split('\0', 1)
Then just use text and if you need rest you've got it for later...
Note that in the case of splitting once, then str.partition is preferred, eg:
text, rest = str_from_c.partition('\0')[::2]
As this ensures there's always a 3-tuple result so that unpacking will always be successful even if no actual split occurred.
How I can despise the second part?
Just do not send it?
The server code probably looks like this:
char buffer[123];
<init buffer partially, terminating the the part with a 0 >
write(..., buffer, 123);
Change it to be
write(..., buffer, strlen(buffer) + 1);

Writing and reading headers with struct

I have a file header which I am reading and planning on writing which contains information about the contents; version information, and other string values.
Writing to the file is not too difficult, it seems pretty straightforward:
outfile.write(struct.pack('<s', "myapp-0.0.1"))
However, when I try reading back the header from the file in another method:
header_version = struct.unpack('<s', infile.read(struct.calcsize('s')))
I have the following error thrown:
struct.error: unpack requires a string argument of length 2
How do I fix this error and what exactly is failing?
Writing to the file is not too difficult, it seems pretty straightforward:
Not quite as straightforward as you think. Try looking at what's in the file, or just printing out what you're writing:
>>> struct.pack('<s', 'myapp-0.0.1')
'm'
As the docs explain:
For the 's' format character, the count is interpreted as the size of the string, not a repeat count like for the other format characters; for example, '10s' means a single 10-byte string, while '10c' means 10 characters. If a count is not given, it defaults to 1.
So, how do you deal with this?
Don't use struct if it's not what you want. The main reason to use struct is to interact with C code that dumps C struct objects directly to/from a buffer/file/socket/whatever, or a binary format spec written in a similar style (e.g. IP headers). It's not meant for general serialization of Python data. As Jon Clements points out in a comment, if all you want to store is a string, just write the string as-is. If you want to store something more complex, consider the json module; if you want something even more flexible and powerful, use pickle.
Use fixed-length strings. If part of your file format spec is that the name must always be 255 characters or less, just write '<255s'. Shorter strings will be padded, longer strings will be truncated (you might want to throw in a check for that to raise an exception instead of silently truncating).
Use some in-band or out-of-band means of passing along the length. The most common is a length prefix. (You may be able to use the 'p' or 'P' formats to help, but it really depends on the C layout/binary format you're trying to match; often you have to do something ugly like struct.pack('<h{}s'.format(len(name)), len(name), name).)
As for why your code is failing, there are multiple reasons. First, read(11) isn't guaranteed to read 11 characters. If there's only 1 character in the file, that's all you'll get. Second, you're not actually calling read(11), you're calling read(1), because struct.calcsize('s') returns 1 (for reasons which should be obvious from the above). Third, either your code isn't exactly what you've shown above, or infile's file pointer isn't at the right place, because that code as written will successfully read in the string 'm' and unpack it as 'm'. (I'm assuming Python 2.x here; 3.x will have more problems, but you wouldn't have even gotten that far.)
For your specific use case ("file header… which contains information about the contents; version information, and other string values"), I'd just use write the strings with newline terminators. (If the strings can have embedded newlines, you could backslash-escape them into \n, use C-style or RFC822-style continuations, quote them, etc.)
This has a number of advantages. For one thing, it makes the format trivially human-readable (and human-editable/-debuggable). And, while sometimes that comes with a space tradeoff, a single-character terminator is at least as efficient, possibly more so, than a length-prefix format would be. And, last but certainly not least, it means the code is dead-simple for both generating and parsing headers.
In a later comment you clarify that you also want to write ints, but that doesn't change anything. A 'i' int value will take 4 bytes, but most apps write a lot of small numbers, which only take 1-2 bytes (+1 for a terminator/separator) if you write them as strings. And if you're not writing small numbers, a Python int can easily be too large to fit in a C int—in which case struct will silently overflow and just write the low 32 bits.

Categories

Resources