mirror of
https://github.com/hakril/PythonForWindows
synced 2026-06-08 14:31:45 +00:00
Add missing psid.py + some rpc fix + alpc sample + wincli
This commit is contained in:
@@ -0,0 +1,40 @@
|
||||
import multiprocessing
|
||||
|
||||
import windows.alpc
|
||||
from windows.generated_def import LPC_CONNECTION_REQUEST, LPC_REQUEST
|
||||
|
||||
PORT_NAME = r"\RPC Control\YOLOPORT"
|
||||
|
||||
def alpc_server():
|
||||
server = windows.alpc.AlpcServer(PORT_NAME)
|
||||
print("[SERV] PORT CREATED")
|
||||
attrs, msg = server.wait_data()
|
||||
print("[SERV] Message type = {0:#x}".format(msg.u2.s2.Type))
|
||||
print("[SERV] Received data: <{0}>".format(msg.data))
|
||||
if msg.u2.s2.Type & LPC_CONNECTION_REQUEST:
|
||||
print("[SERV] Connection request")
|
||||
msg.data = "WOKAY"
|
||||
server.accept_connection(msg)
|
||||
attrs, msg = server.wait_data()
|
||||
print("[SERV] Received message")
|
||||
print("[SERV] Message type = {0:#x}".format(msg.u2.s2.Type))
|
||||
if msg.u2.s2.Type & LPC_REQUEST:
|
||||
print("[SERV] ALPC request: <{0}>".format(msg.data))
|
||||
server.reply(msg, "REQUEST '{0}' DONE".format(msg.data))
|
||||
|
||||
|
||||
def alpc_client():
|
||||
client = windows.alpc.AlpcClient()
|
||||
connect_response = client.connect_to_port(PORT_NAME, "COUCOU")
|
||||
print("[CLIENT] Connected: {0}".format(connect_response.data))
|
||||
print("[CLIENT] Send Message <POUET>")
|
||||
attr, response = client.send_receive("POUET")
|
||||
print("[CLIENT] Server response: <{0}>".format(response.data))
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
proc = multiprocessing.Process(target=alpc_server, args=())
|
||||
proc.start()
|
||||
import time; time.sleep(0.5)
|
||||
alpc_client()
|
||||
print("BYE")
|
||||
@@ -0,0 +1,219 @@
|
||||
import argparse
|
||||
import os.path
|
||||
import windows
|
||||
import windows.generated_def as gdef
|
||||
|
||||
def find_processes_from_kwargs(pid=None, name=None, **kwargs):
|
||||
if pid is None and name is None:
|
||||
return windows.system.processes
|
||||
if pid is not None:
|
||||
return [p for p in windows.system.processes if p.pid == pid]
|
||||
return [p for p in windows.system.processes if p.name.lower() == name.lower()]
|
||||
|
||||
def find_one_process_from_kwargs(pid=None, name=None, **kwargs):
|
||||
if pid is not None:
|
||||
targets = [p for p in windows.system.processes if p.pid == pid]
|
||||
if not len(targets):
|
||||
raise ValueError("Could not find process with pid <{0}>".format(pid))
|
||||
assert len(targets) == 1
|
||||
return targets[0]
|
||||
|
||||
targets = [p for p in windows.system.processes if p.name.lower() == name.lower()]
|
||||
if not len(targets):
|
||||
raise ValueError("Could not find a process with name <{0}>".format(name))
|
||||
# Ask to choose a process
|
||||
if len(targets) == 1:
|
||||
return targets[0]
|
||||
print("Multiple process with name {0}, please choose:".format(name))
|
||||
for i, proc in enumerate(targets):
|
||||
print(" {0}) {1}".format(i, proc))
|
||||
choice = raw_input("Number > ")
|
||||
try:
|
||||
return targets[choice]
|
||||
except IndexError:
|
||||
raise
|
||||
|
||||
|
||||
def proc_command_list(**kwargs):
|
||||
print("Listing processes")
|
||||
for proc in find_processes_from_kwargs(**kwargs):
|
||||
print (proc)
|
||||
|
||||
def proc_command_shell(**kwargs):
|
||||
target = find_one_process_from_kwargs(**kwargs)
|
||||
pfw_path = os.path.dirname(windows.__path__[0])
|
||||
print("Using PythonForWindows at <{0}>".format(pfw_path))
|
||||
try:
|
||||
target.execute_python("import sys; sys.path.append(r'{0}')".format(pfw_path))
|
||||
target.execute_python("import windows; windows.utils.pop_shell()")
|
||||
except Exception as e:
|
||||
print("Error while injecting python code: <{0!r}>".format(e))
|
||||
raise
|
||||
|
||||
def proc_command_kill(**kwargs):
|
||||
target = find_one_process_from_kwargs(**kwargs)
|
||||
print(target.exit(0))
|
||||
print(target)
|
||||
|
||||
def proc_command_killall(**kwargs):
|
||||
targets = find_processes_from_kwargs(**kwargs)
|
||||
for target in targets:
|
||||
target.exit(0)
|
||||
print(target)
|
||||
|
||||
|
||||
PAGE_PROTECTIONS = [
|
||||
gdef.PAGE_NOACCESS,
|
||||
gdef.PAGE_READONLY,
|
||||
gdef.PAGE_READWRITE,
|
||||
gdef.PAGE_WRITECOPY,
|
||||
gdef.PAGE_EXECUTE,
|
||||
gdef.PAGE_EXECUTE_READ,
|
||||
gdef.PAGE_EXECUTE_READWRITE,
|
||||
gdef.PAGE_EXECUTE_WRITECOPY,
|
||||
gdef.PAGE_GUARD,
|
||||
gdef.PAGE_NOCACHE,
|
||||
gdef.PAGE_WRITECOMBINE,
|
||||
]
|
||||
PAGE_PROTECTIONS_MAPPER = {x:x for x in PAGE_PROTECTIONS}
|
||||
|
||||
MEMORY_STATE = [gdef.MEM_COMMIT,
|
||||
gdef.MEM_RESERVE,
|
||||
gdef.MEM_DECOMMIT ,
|
||||
gdef.MEM_RELEASE,
|
||||
gdef.MEM_FREE,
|
||||
gdef.MEM_PRIVATE,
|
||||
gdef.MEM_MAPPED,
|
||||
gdef.MEM_RESET,
|
||||
gdef.MEM_TOP_DOWN ,
|
||||
gdef.MEM_WRITE_WATCH,
|
||||
gdef.MEM_PHYSICAL,
|
||||
gdef.MEM_ROTATE,
|
||||
gdef.MEM_LARGE_PAGES,
|
||||
gdef.MEM_4MB_PAGES]
|
||||
MEMORY_STATE_MAPPER = {x:x for x in MEMORY_STATE}
|
||||
|
||||
def proc_command_addr(**kwargs):
|
||||
target = find_one_process_from_kwargs(**kwargs)
|
||||
print(target)
|
||||
for addr in kwargs["addresses"]:
|
||||
print("== Address <{0:#x}> ==".format(addr, target))
|
||||
data = target.query_memory(addr)
|
||||
|
||||
print("* BaseAddress = {0:#x}".format(data.BaseAddress))
|
||||
print("* RegionSize = {0:#x}".format(data.RegionSize))
|
||||
print("* State = {0}".format(MEMORY_STATE_MAPPER.get(data.RegionSize, data.RegionSize)))
|
||||
print("* Protect = {0}".format(PAGE_PROTECTIONS_MAPPER.get(data.Protect, data.Protect)))
|
||||
print('* MappedFile = "{0}"'.format(target.get_mapped_filename(addr)))
|
||||
|
||||
x = work_set = target.query_working_setex([addr])
|
||||
attrs = x[0].VirtualAttributes
|
||||
if attrs.valid:
|
||||
print('* Shared = {0}'.format(bool(attrs.shared)))
|
||||
|
||||
# Module
|
||||
for mod in target.peb.modules:
|
||||
if mod.baseaddr <= addr < mod.baseaddr + mod.SizeOfImage:
|
||||
break
|
||||
else:
|
||||
print("Not in a module")
|
||||
return
|
||||
print("Part of {0}".format(mod))
|
||||
print(" * {0} + {1:#x}".format(mod.name, addr - mod.baseaddr))
|
||||
|
||||
exports = mod.pe.exports
|
||||
res = (0xfffffff, "NOTFOUND")
|
||||
for name, exportaddr in exports.items():
|
||||
if isinstance(name, (int, long)):
|
||||
continue
|
||||
if exportaddr > addr:
|
||||
continue
|
||||
dist = addr - exportaddr
|
||||
res = min((dist, name), res)
|
||||
if dist == 0:
|
||||
break
|
||||
if res[1] != "NOTFOUND":
|
||||
print(" * {0}!{1}+{2:#x}".format(mod.name, res[1], dist))
|
||||
|
||||
# Services
|
||||
|
||||
def find_services_from_kwargs(name=None, **kwargs):
|
||||
if name is None:
|
||||
return windows.system.services
|
||||
return [p for p in windows.system.services if p.name.lower() == name.lower()]
|
||||
|
||||
|
||||
def find_one_service_from_kwargs(name=None, **kwargs):
|
||||
targets = [s for s in windows.system.services if s.name.lower() == name.lower()]
|
||||
if not len(targets):
|
||||
raise ValueError("Could not find a service with name <{0}>".format(name))
|
||||
# Ask to choose a process
|
||||
if len(targets) == 1:
|
||||
return targets[0]
|
||||
print("Multiple services with name {0}, please choose:".format(name))
|
||||
for i, serv in enumerate(targets):
|
||||
print(" {0}) {1}".format(i, serv))
|
||||
choice = raw_input("Number > ")
|
||||
try:
|
||||
return targets[choice]
|
||||
except IndexError:
|
||||
raise
|
||||
|
||||
def serv_command_list(**kwargs):
|
||||
print("Listing services")
|
||||
for serv in find_services_from_kwargs(**kwargs):
|
||||
print (serv)
|
||||
|
||||
def serv_command_start(**kwargs):
|
||||
serv = find_one_service_from_kwargs(**kwargs)
|
||||
serv.start()
|
||||
serv = find_one_service_from_kwargs(**kwargs)
|
||||
print(serv)
|
||||
|
||||
parser = argparse.ArgumentParser(prog=__file__)
|
||||
subparsers = parser.add_subparsers(description='valid subcommands',)
|
||||
|
||||
# Processes commandes
|
||||
proc_parser = subparsers.add_parser('proc')
|
||||
proc_parser.set_defaults(func=proc_command_list)
|
||||
|
||||
group = proc_parser.add_mutually_exclusive_group()
|
||||
group.add_argument('--pid', type=int, help='The pid of the process')
|
||||
group.add_argument('--name', help='The name of the process')
|
||||
|
||||
proc_subparsers = proc_parser.add_subparsers(description='valid subcommands',)
|
||||
|
||||
proc_list_parser_ = proc_subparsers.add_parser('list')
|
||||
proc_list_parser_.set_defaults(func=proc_command_list)
|
||||
|
||||
proc_inject_parser = proc_subparsers.add_parser('shell')
|
||||
proc_inject_parser.set_defaults(func=proc_command_shell)
|
||||
|
||||
proc_inject_parser = proc_subparsers.add_parser('kill')
|
||||
proc_inject_parser.set_defaults(func=proc_command_kill)
|
||||
|
||||
proc_inject_parser = proc_subparsers.add_parser('killall')
|
||||
proc_inject_parser.set_defaults(func=proc_command_killall)
|
||||
|
||||
proc_addr_parser = proc_subparsers.add_parser('addr')
|
||||
proc_addr_parser.set_defaults(func=proc_command_addr)
|
||||
proc_addr_parser.add_argument('addresses', type=lambda x: int(x, 0), nargs="+", help='The addresses to explore')
|
||||
|
||||
# Services commandes
|
||||
serv_parser = subparsers.add_parser('serv')
|
||||
serv_parser.set_defaults(func=proc_command_list)
|
||||
|
||||
group = serv_parser.add_mutually_exclusive_group()
|
||||
group.add_argument('--name', help='The name of the service')
|
||||
|
||||
serv_subparsers = serv_parser.add_subparsers(description='valid subcommands',)
|
||||
|
||||
serv_list_parser_ = serv_subparsers.add_parser('list')
|
||||
serv_list_parser_.set_defaults(func=serv_command_list)
|
||||
|
||||
serv_list_parser_ = serv_subparsers.add_parser('start')
|
||||
serv_list_parser_.set_defaults(func=serv_command_start)
|
||||
|
||||
if __name__ == "__main__":
|
||||
res = parser.parse_args()
|
||||
res.func(**res.__dict__)
|
||||
@@ -1,3 +1,3 @@
|
||||
from client import RPC_SYNTAX_IDENTIFIER, RPCClient
|
||||
import ndr
|
||||
from epmapper import find_alpc_endpoint_and_connect, construct_alpc_tower
|
||||
from client import RPC_SYNTAX_IDENTIFIER, RPCClient
|
||||
from epmapper import find_alpc_endpoint_and_connect, endpoint_map_alpc, construct_alpc_tower
|
||||
@@ -41,7 +41,9 @@ KNOW_RESPONSE_TYPE = {
|
||||
|
||||
KNOWN_RPC_ERROR_CODE = {
|
||||
1783 : "RPC_X_BAD_STUB_DATA",
|
||||
1717 : "RPC_S_UNKNOWN_IF"
|
||||
1717 : "RPC_S_UNKNOWN_IF",
|
||||
1745 : "RPC_S_PROCNUM_OUT_OF_RANGE"
|
||||
|
||||
}
|
||||
|
||||
NOT_USED = 0xBAADF00D
|
||||
|
||||
+6
-1
@@ -34,7 +34,7 @@ class NdrUniquePTR(object):
|
||||
def pack(self, data):
|
||||
subpack = self.subcls.pack(data)
|
||||
if subpack is None:
|
||||
return dword_pad(0)
|
||||
return pack_dword(0)
|
||||
return pack_dword(0x02020202) + subpack
|
||||
|
||||
def pack_in_struct(self, data, id):
|
||||
@@ -75,6 +75,11 @@ class NdrWString(object):
|
||||
result += data
|
||||
return dword_pad(result)
|
||||
|
||||
# @classmethod
|
||||
# def unpack(self, stream):
|
||||
# maxcount, offset, count = stream.partial_unpack("<3I")
|
||||
# return maxcount, offset, count
|
||||
|
||||
class NdrLong(object):
|
||||
@classmethod
|
||||
def pack(cls, data):
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
from windows.generated_def import PSID
|
||||
from windows import winproxy
|
||||
|
||||
class EPSID(PSID):
|
||||
def __repr__(self):
|
||||
return '<Sid "{0}" at {1:#8x}>'.format(str(self), id(self))
|
||||
|
||||
def __str__(self):
|
||||
sid_str = LPCSTR()
|
||||
winproxy.ConvertSidToStringSidA(self, sid_str)
|
||||
result = sid_str.value
|
||||
winproxy.LocalFree(sid_str)
|
||||
return result
|
||||
|
||||
@classmethod
|
||||
def from_string(cls, sidstr):
|
||||
self = cls()
|
||||
winproxy.ConvertStringSidToSidA(sidstr, self)
|
||||
return self
|
||||
Reference in New Issue
Block a user