PythonForWindows
PythonForWindows copied to clipboard
Fix TypeError bug
Hi,
Great project.
I used a simple RPC example to run the server.
I had a bug when I used James Forshaw function Get-RpcAlpcServer, from his RPC tool (NtObjectManager).
The application throw an error:
File "C:\Users\Administrator\AppData\Local\Programs\Python\Python310\lib\site-packages\windows\alpc.py", line 164, in write_data
self.raw_buffer[self.header_size: self.header_size + len(data)] = data
TypeError: one character bytes, bytearray or integer expected
I fixed it by returning the data as bytes.
Hi, Thank you for the PR. In order to better identify the cause, implication of the bug and potential similar bug in the code I would like to write an associated test. Do you have any information about the code that triggered the bug ? Is it in the code of a python RPC server ? What were the types involved ?
Thank you,
Yes, I noticed it happens after the initializing of the client:
client = windows.alpc.AlpcClient(PORT_NAME)
It then go to the __init__ function of AlpcClient and calls (link):
x = self.connect_to_port(port_name, "")
The connect_message is being set as ".
When there is an assignment to send_msg.data (link), it throws the error. This is the assignment:
send_msg.data = connect_message
After stepping into the above assignment it goes to write_data function and you can see the value of data which is ":

Notice that I am using latest Python version 3.10 and this is the code to reproduce it (tested on two systems):
import multiprocessing
import windows.alpc
from windows.generated_def import LPC_CONNECTION_REQUEST, LPC_REQUEST
PORT_NAME = r"\RPC Control\PythonForWindowsPORT"
def alpc_server():
server = windows.alpc.AlpcServer(PORT_NAME) # Create the ALPC Port
print("[SERV] PORT <{0}> CREATED".format(PORT_NAME))
msg = server.recv() # Wait for a message
print("[SERV] Message type = {0:#x}".format(msg.type))
print("[SERV] Received data: <{0}>".format(msg.data))
assert msg.type & 0xfff == LPC_CONNECTION_REQUEST # Check that message is a connection request
print("[SERV] Connection request")
server.accept_connection(msg)
msg = server.recv() # Wait for a real message
print("")
print("[SERV] Received message: <{0}>".format(msg.data))
print("[SERV] Message type = {0:#x}".format(msg.type))
assert msg.type & 0xfff == LPC_REQUEST
# We can reply by two ways:
# - Send the same message with modified data
# - Recreate a Message and copy the MessageId
msg.data = "REQUEST '{0}' DONE".format(msg.data)
server.send(msg)
def alpc_client():
print("Client pid = {0}".format(windows.current_process.pid))
# Creation an 'AlpcClient' with a port name will connect to the port with an empty message
client = windows.alpc.AlpcClient(PORT_NAME)
print("[CLIENT] Connected: {0}".format(client))
# Send a message / wait for the response
response = client.send_receive("Hello world !")
print("[CLIENT] Response: <{0}>".format(response.data))
# You can also send message without waiting for a response with 'client.send'
if __name__ == "__main__":
proc = multiprocessing.Process(target=alpc_server, args=())
proc.start()
import time; time.sleep(0.5)
alpc_client()
print("BYE")
proc.terminate()