I'm trying to attach my Python program to this kernel level exe called "ntoskrnl.exe" and write to its memory.
However I'm unable to attach my program to "ntoskrnl.exe" via pymem or readwritememory and was wondering if someone could help me attach my program to "ntoskrnl.exe" and get its base address and write to it's memory.
I've so far tried pymem:
pm = pymem.Pymem("ntoskrnl.exe")
base = pm.base_address
and Readwritememory:
rwm = ReadWriteMemory()
process = rwm.get_process_by_name("ntoskrnl.exe")
both give me the process not found error! Any help on how to attach my program to the kernel level process and get it's base address would be greatly appreciated! Thanks
I've been trying this too. All I could find in regards so far is this:
def get_base_address(driver=None):
""" Returns base address of kernel modules """
if platform.architecture()[0] == "64bit":
lpImageBase = (c_ulonglong * 1024)()
lpcbNeeded = c_longlong()
psapi.GetDeviceDriverBaseNameA.argtypes = [c_longlong, POINTER(c_char), c_uint32]
else:
lpImageBase = (c_ulong * 1024)()
lpcbNeeded = c_long()
driver_name_size = c_long()
driver_name_size.value = 48
psapi.EnumDeviceDrivers(byref(lpImageBase), c_int(1024), byref(lpcbNeeded))
for base_addr in lpImageBase:
driver_name = c_char_p("\x00" * driver_name_size.value)
if base_addr:
psapi.GetDeviceDriverBaseNameA(base_addr, driver_name, driver_name_size.value)
if driver == None and driver_name.value.lower().find("krnl") != -1:
print("[+] Retrieving kernel info...")
print("[+] Kernel version: {:s}".format(driver_name.value))
print("[+] Kernel base address: {:#x}".format(base_addr))
return (base_addr, driver_name.value)
elif driver_name.value.lower() == driver:
print("[+] Retrieving {:s} info...".format(driver_name))
print("[+] {:s} base address: {:#x}".format(driver_name, base_addr))
return (base_addr, driver_name.value)
return None
get_base_address("ntoskrnl.exe")
I'm just happy that I'm not alone in the wild chase XD!
Related
I am trying to read memory from a process (gameboy advance emulator) in Python using ReadProcessMemory. There is a memory viewer and I am supposed to get 81 at 0xD273 (see picture). I am new to this, I tried to do everything correctly by adding reference in the ReadProcessMemory, but there might be some things that are wrong. I am pretty sure I have the right process id since it matches the one in the task manager.
When I run my code, I get random byte values that are different everytime. 15, 255, 11, 195, but I think I should be getting 81.
I need to use python 32-bit to run the script otherwise I get error 299 (ERROR_PARTIAL_COPY).
Is there something that I'm doing wrong? I don’t specify the base address but I assumed it’s handled by the processHandle.
Here is my code and an example of the output:
result: 1, err code: 0, bytesRead: 1
data: 0000000000000015h
21
import ctypes as c
from ctypes import wintypes as w
import psutil
# Must use py -3-32 vba_script.py
vba_process_id = [p.pid for p in psutil.process_iter() if "visualboyadvance" in p.name()][0]
pid = vba_process_id # I assume you have this from somewhere.
k32 = c.WinDLL('kernel32', use_last_error=True)
OpenProcess = k32.OpenProcess
ReadProcessMemory = k32.ReadProcessMemory
CloseHandle = k32.CloseHandle
processHandle = OpenProcess(0x10, False, pid)
addr = c.c_void_p(0xD273)
dataLen = 8
data = c.c_byte()
bytesRead = c.c_byte()
result = ReadProcessMemory(processHandle, c.byref(addr), c.byref(data), c.sizeof(data), c.byref(bytesRead))
e = c.get_last_error()
print('result: {}, err code: {}, bytesRead: {}'.format(result,e,bytesRead.value))
print('data: {:016X}h'.format(data.value))
print(data.value)
CloseHandle(processHandle)
After reading #jasonharper answer, I found a way to get the actual address in the memory.
To get them, I used Cheat Engine, here was my procedure:
In Cheat Engine, search for 87949181 (hex for BRUH, which is trainer's name). Any data that you know will not change is also fine.
Find the address that really corresponds to it. Should have 0x00000050, 0x01000000, 0x0000FF99, 0x99000000, 0x00001600, 0x212D0316, DC00002D after (see picture 1). This address is a pointer. In my case, it's 0x07D2F370 (picture 2).
Double click on the address and do a pointer scan. In my case, the pointer address 0x07D2F218. This is a dynamic address that will change everytime, so you need to find the static address.
You can find that "visualboyadvance-m.exe"+02224064 -> 07D2F218. The base address is therefore 0x07D2F218 - 0x02224064 = 0x9a0000. The static address offset for the data I'm searching for is 0x02224064. The offset for the trainer's name data is 0x158.
After opening the process, to search in the memory, you can have a code like this:
base_addr = 0x9a0000 # "visualboyadvance-m.exe"
static_addr_offset = 0x02224064
address = base_addr + static_addr_offset + 0x158
k32 = c.WinDLL('kernel32', use_last_error=True)
buffer = c.create_string_buffer(buffer_size)
buffer_size=32
bytes_read = c.c_ulong(0)
if k32.ReadProcessMemory(processHandle, address, buffer, buffer_size, c.byref(bytes_read)):
data = c.c_uint32.from_buffer(buffer)
print(f"data: {data .value:X}")
This returns the right data that I'm looking for: data: 87949181.
Here are the pictures:
================================================================
================================================================
Bonus:
The base address will change if you close the game and you will need to find it back everytime. There is some way of doing way it by getting the module with the name of the process pname. You can get it easily with psutil.
import win32process
import psutils
vba_process = [p for p in psutil.process_iter() if "visualboyadvance" in p.name()][0]
pid = vba_process.pid
pname = vba_process.name
k32 = c.WinDLL('kernel32', use_last_error=True)
processHandle = k32.OpenProcess(0x10, False, pid)
modules = win32process.EnumProcessModules(processHandle)
for module in modules:
moduleFileName = win32process.GetModuleFileNameEx(processHandle, module)
if pname in moduleFileName:
base_address = module
print("Success: Got Base Address:", hex(base_address))
Success: Got Base Address: 0x9a0000
Edit: Found how to get base address of process automatically
So I'm trying to make a transaction using the Bit library. Everything was working on testnet, but once I tried my script on mainnet, it return this error everytime :
ConnectionError: Transaction broadcast failed, or Unspents were
already used.
I tried to wait (until some additional confirmations, checked that both wallets where in mainnet but I can't get it to work... Here is my code :
if sys.argv[1] == 'withdraw':
if len(sys.argv) > 3:
my_key = Key(sys.argv[2])
my_key.get_balance()
total_bytes = (148 * len(my_key.get_unspents())) + (34 * 2) + 10 + len(my_key.get_unspents())
total_fees = total_bytes * network.get_fee(fast=True)
tx_hash = my_key.send([(sys.argv[3], int(my_key.balance_as('satoshi')) - total_fees, 'satoshi')])
print('{"status": "success","tx_hash":'+tx_hash+'}')
So I just saw that the Bit documentation had an option to move all funds from a wallet to another :
tx_hash = my_key.send([], leftover=sys.argv[3])
leave the outputs blank and put your address in leftover :)
I am using python rally toolkit version 1.4.2 to perform get and put operations but sometimes whenever I run my code i get this error : """File "/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/pyral/rallyresp.py", line 303, in next
if (self._served >= self._servable) or (self._limit and self._served >= self._limit):
AttributeError: 'RallyRESTResponse' object has no attribute '_servable'"""
On re-running the same code multiple times the code works and sometimes it doesn't. Below is the code in rallyresp.py file which is raising the exception.
if (self._served >= self._servable) or (self._limit and self._served >= self._limit):
raise StopIteration
Here is my complete python code:
class TestExecutionDetails():
def __init__(self):
self.testCaseDetailDict = collections.defaultdict(list)
self.userStoryDetailDict = collections.defaultdict(list)
self.conf = ConfigObj("config.ini")
self.server = self.conf['RallyWS_P']['server']
self.ws = self.conf['RallyWS_P']['workspace']
self.prj = self.conf['RallyWS_P']['project']
self.apikey = self.conf['LoginCredentials']['apikey']
self.userStoryHeaderCount = 0
self.testCaseHeaderCount = 0
print(self.apikey,"\t\t",self.server,"\t\t",self.ws,"\t\t",self.prj)
self.rally = Rally(self.server, apikey=self.apikey, workspace=self.ws, project=self.prj)
self.rally.enableLogging('rally.simple-use.log')
def getTestExecutionInfo(self):
story = self.rally.get('UserStory', query='Release.Name contains "AXP PI 20.2" AND Iteration.Name contains "AXP 20.2.10 IP"', fetch=True,order="Iteration,FormattedID")
if not story.errors:
for s in story:
self.userStoryDetailDict['FormattedID'].append(s.FormattedID)
self.userStoryDetailDict['Iteration'].append(s.Iteration.Name)
self.userStoryDetailDict['Release'].append(s.Release.Name)
self.userStoryDetailDict['LastBuild'].append(s.LastBuild)
self.userStoryDetailDict['LastRun'].append(str(s.LastRun).split('T')[0])
self.userStoryDetailDict['Owner'].append(s.Owner.DisplayName)
self.userStoryDetailDict['TcCount'].append(s.TestCaseCount)
self.userStoryDetailDict['PassingTcCount'].append(s.PassingTestCaseCount)
self.userStoryDetailDict['TcStatus'].append(s.TestCaseStatus)
for t in s.TestCases:
#print(t.Owner,"\t\t",t.Owner.DisplayName)
self.testCaseDetailDict['FormattedID'].append(t.FormattedID)
self.testCaseDetailDict['CreatedBy'].append(t.CreatedBy.DisplayName)
if t.Owner is None:
self.testCaseDetailDict['Owner'].append("None")
else:
self.testCaseDetailDict['Owner'].append(t.Owner.DisplayName)
self.testCaseDetailDict['LastBuild'].append(t.LastBuild)
#self.testCaseDetailDict['LastResult'].append(t.TestCaseResult.Name)
self.testCaseDetailDict['LastRun'].append(str(t.LastRun).split('T')[0])
self.testCaseDetailDict['LastUpdateDate'].append(str(t.LastUpdateDate).split('T')[0])
self.testCaseDetailDict['LastVerdict'].append(t.LastVerdict)
#self.testCaseDetailDict['Attachments'].append(t.Attachement.Name)
self.userStoryHeaderCount = len(self.userStoryDetailDict.keys())
self.testCaseHeaderCount = len(self.testCaseDetailDict.keys())
print(self.testCaseDetailDict)
print(self.userStoryDetailDict)
if __name__ == '__main__':
ted = TestExecutionDetails()
ted.getTestExecutionInfo()
As suggested by #ewong, it was indeed a network issue. The connection was getting lost in-between due to internet connectivity as most of us are working at home. The solution I have tried for this is to add max 5 retries.
I have two devices that each have their usb-serial connector. The usb-serial connection gives access to 3 COM ports for communication to different chips on each device.
I want to create a function initialise() that automatically scans and hooks up to the COM ports of the device which isnt in use yet.
I currently have the following, but it fails to hook up with the second device when I run the function twice and I am stuck right now so I need a clever suggestion.
def initialise():
PORTMAPPINGWIN = {'fwmain': ('COM8','COM12','COM4'),
'fwutil': ('COM9','COM13','COM5'),
'fwcif': ('COM10','COM14','COM6')}
PORTMAPPINGMAC = {'fwmain': ('/dev/tty.usbserial-000013FAB','/dev/tty.usbserial-12345B'),
'fwutil': ('/dev/tty.usbserial-000013FAC','/dev/tty.usbserial-12345C'),
'fwcif': ('/dev/tty.usbserial-000013FAD','/dev/tty.usbserial-12345D')}
if os.name == 'nt':
_portmap = PORTMAPPINGWIN
else:
_portmap = PORTMAPPINGMAC
_available = []
_n = len(_portmap['fwmain'])
for portaddress in range(_n):
for termname in _portmap.keys():
usb = _portmap[termname][portaddress]
try:
_ser = serial.Serial(usb, 115200)
_ser.close()
_available.append(usb)
except serial.SerialException:
pass
_available.sort()
if _available != [] and _available != None:
if _available[0] == 'COM10': #TODO use a regex instead to replace all COM5 instances with COM05 so that we can sort properly list('COM5').insert(re.search(r'(?<=COM)\d', 'COM5').start(), '0')
if len(_available) < 4:
_available.insert(3, _available.pop(0))
elif len(_available) < 7:
_available.insert(6, _available.pop(0))
elif len(_available) < 10:
_available.insert(9, _available.pop(0))
print([port for port in _available])
if len(_available) > 3:
_available = _available[:3]
Hmmm. I changed except serial.SerialException: to except Exception: and now it works fine.
Thank you me.
I think this is a cool procedure for anyone who want to start the same script on multiple attached devices. And if you dont want to pre-specify the COM ports that the device is listed at, you could just replace
for portaddress in range(_n):
for termname in _portmap.keys():
usb = _portmap[termname][portaddress]
with for usb in range(255): usb = 'COM' + str(usb) or something like that..
I have the following code so far that tells me every time a new process is created.
import wmi
c = wmi.WMI()
process_watcher = c.Win32_Process.watch_for("creation")
while True:
new_process = process_watcher()
print(new_process.Caption)
print(new_process.ExecutablePath)
This works fine, but what I'm really trying to do is get at the Processes Description because while the filename of what I'm looking for might change, the description does not. I can't find anything in Win32_Process or win32file that gets me the file description though. Does anybody know how to do this?
Thanks!
while True:
try:
new_process = process_watcher()
proc_owner = new_process.GetOwner()
proc_owner = "%s\\%s" % (proc_owner[0],proc_owner[2])
create_date = new_process.CreationDate
executable = new_process.ExecutablePath
cmdline = new_process.CommandLine
pid = new_process.ProcessId
parent_pid = new_process.parentProcessId
privileges = "N/A"
process_log_message = "%s,%s,%s,%s,%s,%s,%s,\r\n" % (create_date,proc_owner,executable,cmdline,pid,parent_pid,privileges)
print "1"
print process_log_message
log_to_file(process_log_message)
except:
print "2"
pass
Hope this helps :)