Python crashes on field access ctypes - winapi

I'm using the ctypes module to call GetTcpTable2.
I've been slowly converting the example here in C++ to Python; but am getting crash during a field access.
if __name__ == "__main__":
ptcp_table = POINTER(MIB_TCPTABLE2)()
ptcp_table = cast(create_string_buffer(sizeof(MIB_TCPTABLE2)),
POINTER(MIB_TCPTABLE2))
ip_addr = in_addr()
size = c_ulong(sizeof(MIB_TCPTABLE2))
retval = GetTcpTable2(ptcp_table, byref(size), TRUE)
if retval == ERROR_INSUFFICIENT_BUFFER:
ptcp_table = cast(create_string_buffer(size.value),
POINTER(MIB_TCPTABLE2))
if not ptcp_table:
#throw error
pass
retval = GetTcpTable2(ptcp_table, byref(size), TRUE)
if retval == NO_ERROR:
print("Entries %d" % ptcp_table[0].dwNumEntries)
for i in range(0, ptcp_table[0].dwNumEntries):
print(ptcp_table[0].table[i])
#ip_addr.S_un.S_addr = ptcp_table[0].table[i].dwLocalAddr
#ip_addr_string = inet_nota(ip_addr)
#print(ip_addr_string)
#print(string_at(ip_addr_string))
It crashes when trying to access dwLocalAddr apart of table[i].
ptcp_table[0].table[i].dwLocalAddr
However it doesn't crash when just printing ptcp_table[0].table[i].
I've tried printing and accessing other fields; but Python just crashes.
Here are my struct definitions:
class MIB_TCPROW2(Structure):
_fields_ = [
("dwState", c_ulong),
("dwLocalAddr", c_ulong),
("dwLocalPort", c_ulong),
("dwRemoteAddr", c_ulong),
("dwRemotePort", c_ulong),
("dwOwningPid", c_ulong),
("dwOffloadState", c_int)
]
class MIB_TCPTABLE2(Structure):
_fields_ = [
("dwNumEntries", c_ulong),
("table", POINTER(MIB_TCPROW2))
]
Definition of GetTcpTable2:
GetTcpTable2 = windll.iphlpapi.GetTcpTable2
GetTcpTable2.argtypes = [POINTER(MIB_TCPTABLE2), POINTER(c_ulong), c_char]
GetTcpTable2.restype = c_ulong
I have a small hunch that in the definition of the MIB_TCPTABLE2 struct; the documentation says that table is an array of MIB_TCPROW2 size ANY_SIZE; and further inspection is that ANY_SIZE is 1 from checking the iphlpapi.h file. And I know that the size of POINTER(MIB_TCPROW2) doesn't equal the size of MIB_TCPROW2.

I looked into other ctypes questions revolving around variable length fields inside of a struct, and came to an answer which suggested to use a factory method to generate the class definitions.
def MIB_TCPTABLE2_FACTORY(size):
class MIB_TCPTABLE2(Structure):
_fields_ = [
("dwNumEntries", c_ulong),
("table", MIB_TCPROW2 * size)
]
return MIB_TCPTABLE2
I can use this knowing the size returned from GetTcpTable2 to create a new type. And then all I have to do is change the argtypes of GetTcpTable2 to accept a void *.
GetTcpTable2.argtypes = [c_void_p, POINTER(c_ulong), c_char]

This is how I solved it. I first got the required size by passing in the following arguments:
ret = windll.iphlpapi.GetTcpTable2(None, byref(tcp_table_size), True)
Notice None is the first argument, which is equivalent to NULL when passing it into ctypes windows function. Then I defined the MIB_TCPTABLE2 class and inside it, I passed in the size returned by the first call to GetTcpTable2:
class MIB_TCPTABLE2(Structure):
_fields_ = [
("dwNumEntries", c_ulong),
("table", MIB_TCPROW2 * tcp_table_size.value),
]
Next, I created an instance of the structure and called GetTcpTable2 again passing in the newly created structure:
tcp_table = MIB_TCPTABL2()
ret = windll.iphlpapi.GetTcpTable2(byref(tcp_table), byref(tcp_table_size), True)
Here's the sample code:
from ctypes import *
import socket
import struct
NO_ERROR = 0
ERROR_INSUFFICIENT_BUFFER = 122
TcpConnectionOffloadStateInHost = 0
TcpConnectionOffloadStateOffloading = 1
TcpConnectionOffloadStateOffloaded = 2
TcpConnectionOffloadStateUploading = 3
TcpConnectionOffloadStateMax = 4
class MIB_TCPROW2(Structure):
_fields_ = [
("dwState", c_ulong),
("dwLocalAddr", c_ulong),
("dwLocalPort", c_ulong),
("dwRemoteAddr", c_ulong),
("dwRemotePort", c_ulong),
("dwOwningPid", c_ulong),
("dwOffloadState", c_ulong),
]
def main():
windll.iphlpapi.GetTcpTable2.argtypes = [c_void_p, POINTER(c_ulong), c_bool]
tcp_table_size = c_ulong()
ret = windll.iphlpapi.GetTcpTable2(None, byref(tcp_table_size), True)
if ret == ERROR_INSUFFICIENT_BUFFER:
class MIB_TCPTABLE2(Structure):
_fields_ = [
("dwNumEntries", c_ulong),
("table", MIB_TCPROW2 * tcp_table_size.value),
]
tcp_table = MIB_TCPTABLE2()
ret = windll.iphlpapi.GetTcpTable2(byref(tcp_table), byref(tcp_table_size), True)
if ret != NO_ERROR:
print("ERROR: GetTcpTable2() failed, error = " + str(ret))
else:
for i in range(tcp_table.dwNumEntries):
dest_ip = socket.inet_ntoa(struct.pack('<L', tcp_table.table[i].dwRemoteAddr))
print("PID: " + str(tcp_table.table[i].dwOwningPid) + ", DEST IP: " + dest_ip)
if __name__ == "__main__":
main()

Related

How to correctly use Distributed Data Parallel when customizing 'parameters' in the model ?

I have customized a parameter in my model:
self.params = list(self.backbone.parameters())
for head in self.headlist:
self.params += list(head.parameters())
When I wrap my model with DDP, an error occurs when defining the optimizer
optimizer = optim.SGD(model.params, lr=FLAGS.lr, momentum=FLAGS.momentum, weight_decay=FLAGS.weight_decay)
AttributeError 'DistributedDataParallel' object has no attribute 'params '
I think the error is probably caused by my customized "self.params"
Is the following code correct:
model = torch.nn.parallel.DistributedDataParallel(model,device_ids=local_rank)
model_without_ddp = model.module
**
optimizer = optim.SGD(model_without_ddp.params, lr=FLAGS.lr, momentum=FLAGS.momentum, weight_decay=FLAGS.weight_decay)
Or is there any simpler code?
###################################
The detailed definition of the network is as follows:
class multiheadModel():
def __init__(self, num_heads, device, model_name):
self.device = device
self.num_heads = num_heads # global+K
if model_name == 'fcn8s':
self.backbone = VGG16_FCN8s(num_classes=19, backbone=1, head=0).to(device)
self.headlist = [VGG16_FCN8s(num_classes=19, backbone=0, head=1).to(device) for i in range(num_heads)]
self.model = VGG16_FCN8s(num_classes=19).to(device)
for name, param in self.backbone.named_parameters():
if ('conv3' in name) or ('conv4' in name):
param.requires_grad = True
else:
param.requires_grad = False
elif model_name == 'deeplab':
self.backbone = Res_Deeplab(num_classes=19, backbone=1, head=0).to(device)
self.headlist = [Res_Deeplab(num_classes=19, backbone=0, head=1).to(device) for i in range(num_heads)]
self.model = Res_Deeplab(num_classes=19).to(device)
for name, param in self.backbone.named_parameters():
if 'layer3' in name:
param.requires_grad = True
else:
param.required_grad = False
else:
print('ERROR : wrong model name')
sys.exit()
self.params = list(self.backbone.parameters())
for head in self.headlist:
self.params += list(head.parameters())
self.loss_fn = None
#self.k2head = {0:2,1:1,2:0,3:0,4:0,5:4,6:4,7:5}
#self.k2head = {0:2,1:1,2:0,3:0,4:0,5:3,6:3,7:4}
self.k2head = {0:2,1:1,2:0,3:0,4:3,5:3,6:4}
# set train and eval mode
def train(self):
self.backbone.train()
for head in self.headlist:
head.train()
def eval(self):
self.backbone.eval()
for head in self.headlist:
head.eval()
def computePredLoss(self, rgb, lbl, k):
x = self.backbone(rgb)
head_id = list(range(self.num_heads))
head_id.remove(self.k2head[k])
input_size = rgb.size()[2:]
loss = 0
for i in head_id:
pred = self.headlist[i](x)
pred = F.interpolate(pred, size=input_size, mode='bilinear', align_corners=True)
loss += self.loss_fn(pred, lbl)
return pred, loss
def forward(self, input):
output = {}
if "label" in input:
self.train()
pred,loss = self.computePredLoss(input['rgb'], input['label'], input['k'])
output['pred'], output['loss']=pred, loss
else:
self.eval()
x = self.backbone(input['rgb'])
k = -1
if "k" in input:
k = self.k2head[input['k']]
pred = self.headlist[k](x)
input_size = input['rgb'].size()[2:]
pred = F.interpolate(pred, size=input_size, mode='bilinear', align_corners=True)
output['pred'] = pred
return output
def validate(self, loader, k=-2):
self.eval()
if k!=-2:
val_metrics = StreamSegMetrics(19)
val_metrics.reset()
with torch.no_grad():
for i, (batch, rgb_batch) in enumerate(loader):
rgb_batch = rgb_batch.to(device=self.device, dtype=torch.float)
batch = batch.to(device=self.device, dtype=torch.int64)
input_size = rgb_batch.size()[2:]
x = self.backbone(rgb_batch)
pred = self.headlist[k](x)
pred = F.interpolate(pred, size=input_size, mode='bilinear', align_corners=True)
preds = pred.detach().max(dim=1)[1].cpu().numpy()
targets = batch.cpu().numpy()
val_metrics.update(targets, preds)
score = val_metrics.get_results()
else:
val_metrics = [StreamSegMetrics(19) for i in range(self.num_heads)]
for metric in val_metrics:
metric.reset()
with torch.no_grad():
for i, (batch, rgb_batch) in enumerate(loader):
rgb_batch = rgb_batch.to(device=self.device, dtype=torch.float)
batch = batch.to(device=self.device, dtype=torch.int64)
input_size = rgb_batch.size()[2:]
x = self.backbone(rgb_batch)
for k in range(self.num_heads):
pred = self.headlist[k](x)
pred = F.interpolate(pred, size=input_size, mode='bilinear', align_corners=True)
preds = pred.detach().max(dim=1)[1].cpu().numpy()
targets = batch.cpu().numpy()
val_metrics[k].update(targets, preds)
score = [val_metrics[k].get_results() for k in range(self.num_heads)]
return score
def getHeadPaths(self, model_path, iteration=-1):
head_paths = []
if '_iter' in model_path:
base_path = model_path.split('_iter')[0]
else:
base_path = model_path.split('.pth')[0]
if iteration==-1:
for i in range(self.num_heads-1):
head_paths.append(base_path+'_except_g'+chr(97+i)+'.pth')
head_paths.append(model_path)
else:
for i in range(self.num_heads-1):
head_paths.append(base_path+'_except_g'+chr(97+i)+'_iter'+str(iteration)+'.pth')
head_paths.append(base_path+'_iter'+str(iteration)+'.pth')
return head_paths
def save(self, model_path, iteration=-1):
self.model.load_state_dict(self.backbone.state_dict(), strict=False)
head_paths = self.getHeadPaths(model_path, iteration)
for i in range(self.num_heads):
self.model.load_state_dict(self.headlist[i].state_dict(), strict=False)
torch.save(self.model.state_dict(), head_paths[i])
def load(self, model_path):
iteration = -1
if '_iter' in model_path:
iteration = int(model_path.split('_iter')[1].split('.pth')[0])
self.model.load_state_dict(torch.load(model_path))
self.backbone.load_state_dict(self.model.state_dict(), strict=False)
head_paths = self.getHeadPaths(model_path, iteration)
existance = 1
for path in head_paths:
if os.path.isfile(path)==False:
existance = 0
if existance==1:
print('loading from multiheads')
for i in range(self.num_heads):
self.model.load_state_dict(torch.load(head_paths[i]))
self.headlist[i].load_state_dict(self.model.state_dict(), strict=False)
else:
print('loading from singlehead')
for i in range(self.num_heads):
self.model.load_state_dict(torch.load(head_paths[-1]))
self.headlist[i].load_state_dict(self.model.state_dict(), strict=False)
def __call__(self, input):
return self.forward(input)

py_environment 'time_step' doesn't match 'time_step_spec'

I have created a custom pyenvironment via tf agents. However I can't validate the environment or take steps within it with py_policy.action
I'm confused as to what is excepted from the time_step_specs
I have tried converting to tf_py_environment via tf_py_environment.TFPyEnvironment and was successful in taking actions with tf_policy but I'm still confused as to the difference.
import abc
import numpy as np
from tf_agents.environments import py_environment
from tf_agents.environments import tf_environment
from tf_agents.environments import tf_py_environment
from tf_agents.environments import utils
from tf_agents.specs import array_spec
from tf_agents.environments import wrappers
from tf_agents.trajectories import time_step as ts
from tf_agents.policies import random_tf_policy
import tensorflow as tf
import tf_agents
class TicTacToe(py_environment.PyEnvironment):
def __init__(self,n):
super(TicTacToe,self).__init__()
self.n = n
self.winner = None
self._episode_ended = False
self.inital_state = np.zeros((n,n))
self._state = self.inital_state
self._observation_spec = array_spec.BoundedArraySpec(
shape = (n,n),dtype='int32',minimum = -1,maximum = 1,name =
'TicTacToe board state spec')
self._action_spec = array_spec.BoundedArraySpec(
shape = (),dtype = 'int32', minimum = 0,maximum = 8, name =
'TicTacToe action spec')
def observation_spec(self):
return self._observation_spec
def action_spec(self):
return self._action_spec
def _reset(self):
return ts.restart(self.inital_state)
def check_game_over(self):
for i in range(self.n):
if (sum(self._state[i,:])==self.n) or
(sum(self._state[:,i])==self.n):
self.winner = 1
return True
elif (sum(self._state[i,:])==-self.n) or
(sum(self._state[:,i])==-self.n):
self.winner = -1
return True
if (self._state.trace()==self.n) or
(self._state[::-1].trace()==self.n):
self.winner = 1
return True
elif (self._state.trace()==-self.n) or (self._state[::-1].trace()==-
self.n):
self.winner = -1
return True
if not (0 in self._state):
return True
def _step(self,action):
self._state[action//3,action%3]=1
self._episode_ended = self.check_game_over
if self._episode_ended==True:
if self.winner == 1:
reward = 1
elif self.winner == None:
reward = 0
else:
reward = -1
return ts.termination(self._state,dtype = 'int32',reward=reward)
else:
return ts.transition(self._state,dtype = 'int32',reward =
0.0,discount = 0.9)
env = TicTacToe(3)
utils.validate_py_environment(env, episodes=5)
This is the error I get:
ValueError Traceback (most recent call last)
in
----> 1 utils.validate_py_environment(env, episodes=5)
C:\Users\bzhang\AppData\Local\Continuum\anaconda3\lib\site-packages\tf_agents\environments\utils.py in validate_py_environment(environment, episodes)
58 raise ValueError(
59 'Given time_step: %r does not match expected time_step_spec: %r' %
---> 60 (time_step, time_step_spec))
61
62 action = random_policy.action(time_step).action
ValueError: Given time_step: TimeStep(step_type=array(0), reward=array(0., dtype=float32), discount=array(1., dtype=float32), observation=array([[0., 0., 0.],
[0., 0., 0.],
[0., 0., 0.]])) does not match expected time_step_spec: TimeStep(step_type=ArraySpec(shape=(), dtype=dtype('int32'), name='step_type'), reward=ArraySpec(shape=(), dtype=dtype('float32'), name='reward'), discount=BoundedArraySpec(shape=(), dtype=dtype('float32'), name='discount', minimum=0.0, maximum=1.0), observation=BoundedArraySpec(shape=(3, 3), dtype=dtype('int32'), name='TicTacToe board state spec', minimum=-1, maximum=1))
Your observation does not match the spec, you need to pass dtype=np.int32 to the np array to make sure the type match.

Stuck filling an array using VBscript and a For Loop

I have created an array to store some excel cell addresses, but while running through a portion of the array with a For Loop (because the values are in order for that portion of the data and its easier than doing each one at a time), but I get an error at line 22,(saData(i,1) = "D" count), right at the "count" variable but I cant figure out why.
'LOADING EXCEL CELL ADDRESS INTO INPUT ARRAY
saData(0,1) = "C3"
saData(1,1) = "F3"
saData(2,1) = "C4"
saData(3,1) = "F4"
saData(4,1) = "F6"
saData(5,1) = "C7"
saData(6,1) = "F7"
saData(7,1) = "C8"
saData(8,1) = "C9"
saData(9,1) = "F9"
saData(10,1) = "C11"
saData(12,1) = "F11"
saData(13,1) = "C13"
saData(14,1) = "F13"
Dim count : count = 16
For i = 15 to 54
saData(i,1) = "D" count
count = count + 1
next'
saData(55,1) = "G59"
saData(56,1) = "F60"
saData(57,1) = "B64"
saData(58,1) = "E64"
For i = 0 to 59
Msgbox saData(i,1)
next
Just try concatenating saData(i,1) = "D"&count

Don't see images on my buttons if I create them with a loop

I'm trying to make a program in Python 3.3.0 to train with Tkinter, but when I try to put images on buttons which are created in a loop, I obtain a few buttons that don't work (I can't click on them and they don't have images), and the last one is working and with the image on it. Here there's the code:
elenco = [immagine1, immagine2, immagine3, immagine 4]
class secondWindow:
def __init__(self):
self.secondWindow = Tk()
self.secondWindow.geometry ('500x650+400+30')
class mainWindow:
def __init__(self):
self.mainWindow = Tk()
self.mainWindow.geometry ('1100x650+100+10')
self.mainWindow.title('MainWindow')
def Buttons(self, stringa):
i = 0
for _ in elenco:
if stringa in _.lower():
j = int(i/10)
self.IM = PIL.Image.open (_ + ".jpg")
self.II = PIL.ImageTk.PhotoImage (self.IM)
self.button = Button(text = _, compound = 'top', image = self.II, command = secondWindow).grid(row = j, column = i-j*10)
i += 1
def mainEnter (self):
testoEntry = StringVar()
self.mainEntry = Entry(self.mainWindow, textvariable = testoEntry).place (x = 900, y = 20)
def search ():
testoEntry2 = testoEntry.get()
if testoEntry2 == "":
pass
else:
testoEntry2 = testoEntry2.lower()
mainWindow.Buttons(self, testoEntry2)
self.button4Entry = Button (self.mainWindow, text = 'search', command = search).place (x = 1050, y = 17)
MW = mainWindow()
MW.mainEnter()
mainloop()
If I try to create buttons in a loop without images, they work:
def Buttons(self, stringa):
i = 0
for _ in elenco:
if stringa in _.lower():
j = int(i/10)
self.button = Button(text = _, command = secondWindow).grid(row = j, column = i-j*10)
i += 1
And if I try to create a button with an image but not in a loop, it works too:
im = PIL.Image.open("immagine1.jpg")
ge = PIL.ImageTk.PhotoImage (im)
butt = Button(text = 'immagine', compound = 'top', image = ge, command = secondWindow).grid(row = 0, column = 0)
Let's say you have images named "image-i.png", i=0,..,9.
When I execute the following code (with python 3.5) I obtain ten working buttons with image and text:
from tkinter import Tk, Button, PhotoImage
root = Tk()
images = []
buttons = []
for i in range(10):
im = PhotoImage(master=root, file="image-%i.png" % i)
b = Button(root, text="Button %i" % i, image=im, compound="left",
command=lambda x=i: print(x))
b.grid(row=i)
images.append(im)
buttons.append(b)
root.mainloop()

Reading memory and Access is Denied

I need to access all memory of a running process in my local Windows 7-64bit. I am new to winapi.
Here is my problem; Whenever I try to Open a process and reads its memory, I get Access is Denied error.
I searched and found something. It is said that If I run the main process as Administrator and use PROCESS_ALL_ACCESS on OpenProcess, I would have enough right to do it as it is said. OK, I did it. but nothing is changed. On reading memory, I still get Access is Denied.
So, I kept searching and found another thing which is enabling SeDebugPrivilege. I have also done that but nothing is changed. I still get the error.
I've read the quest and his answer here;
Windows Vista/Win7 Privilege Problem: SeDebugPrivilege & OpenProcess .
But as I said, I am really new to winapi. I could not solve my problem yet. Is there anything which which I need to configure in my local operating system?
Here is my Python code with pywin32;
from _ctypes import byref, sizeof, Structure
from ctypes import windll, WinError, c_buffer, c_void_p, create_string_buffer
from ctypes.wintypes import *
import win32security
import win32api
import gc
import ntsecuritycon
from struct import Struct
from win32con import PROCESS_ALL_ACCESS
from struct import calcsize
MEMORY_STATES = {0x1000: "MEM_COMMIT", 0x10000: "MEM_FREE", 0x2000: "MEM_RESERVE"}
MEMORY_PROTECTIONS = {0x10: "PAGE_EXECUTE", 0x20: "PAGE_EXECUTE_READ", 0x40: "PAGEEXECUTE_READWRITE",
0x80: "PAGE_EXECUTE_WRITECOPY", 0x01: "PAGE_NOACCESS", 0x04: "PAGE_READWRITE",
0x08: "PAGE_WRITECOPY"}
MEMORY_TYPES = {0x1000000: "MEM_IMAGE", 0x40000: "MEM_MAPPED", 0x20000: "MEM_PRIVATE"}
class MEMORY_BASIC_INFORMATION(Structure):
_fields_ = [
("BaseAddress", c_void_p),
("AllocationBase", c_void_p),
("AllocationProtect", DWORD),
("RegionSize", UINT),
("State", DWORD),
("Protect", DWORD),
("Type", DWORD)
]
class SYSTEM_INFO(Structure):
_fields_ = [("wProcessorArchitecture", WORD),
("wReserved", WORD),
("dwPageSize", DWORD),
("lpMinimumApplicationAddress", DWORD),
("lpMaximumApplicationAddress", DWORD),
("dwActiveProcessorMask", DWORD),
("dwNumberOfProcessors", DWORD),
("dwProcessorType", DWORD),
("dwAllocationGranularity", DWORD),
("wProcessorLevel", WORD),
("wProcessorRevision", WORD)]
class PyMEMORY_BASIC_INFORMATION:
def __init__(self, MBI):
self.MBI = MBI
self.set_attributes()
def set_attributes(self):
self.BaseAddress = self.MBI.BaseAddress
self.AllocationBase = self.MBI.AllocationBase
self.AllocationProtect = MEMORY_PROTECTIONS.get(self.MBI.AllocationProtect, self.MBI.AllocationProtect)
self.RegionSize = self.MBI.RegionSize
self.State = MEMORY_STATES.get(self.MBI.State, self.MBI.State)
# self.Protect = self.MBI.Protect # uncomment this and comment next line if you want to do a bitwise check on Protect.
self.Protect = MEMORY_PROTECTIONS.get(self.MBI.Protect, self.MBI.Protect)
self.Type = MEMORY_TYPES.get(self.MBI.Type, self.MBI.Type)
ASSUME_ALIGNMENT = True
class TARGET:
"""Given a ctype (initialized or not) this coordinates all the information needed to read, write and compare."""
def __init__(self, ctype):
self.alignment = 1
self.ctype = ctype
# size of target data
self.size = sizeof(ctype)
self.type = ctype._type_
# get the format type needed for struct.unpack/pack.
while hasattr(self.type, "_type_"):
self.type = self.type._type_
# string_buffers and char arrays have _type_ 'c'
# but that makes it slightly slower to unpack
# so swap is for 's'.
if self.type == "c":
self.type = "s"
# calculate byte alignment. this speeds up scanning substantially
# because we can read and compare every alignment bytes
# instead of every single byte.
# although if we are scanning for a string the alignment is defaulted to 1 \
# (im not sure if this is correct).
elif ASSUME_ALIGNMENT:
# calc alignment
divider = 1
for i in xrange(4):
divider *= 2
if not self.size % divider:
self.alignment = divider
# size of target ctype.
self.type_size = calcsize(self.type)
# length of target / array length.
self.length = self.size / self.type_size
self.value = getattr(ctype, "raw", ctype.value)
# the format string used for struct.pack/unpack.
self.format = str(self.length) + self.type
# efficient packer / unpacker for our own format.
self.packer = Struct(self.format)
def get_packed(self):
"""Gets the byte representation of the ctype value for use with WriteProcessMemory."""
return self.packer.pack(self.value)
def __str__(self):
return str(self.ctype)[:10] + "..." + " <" + str(self.value)[:10] + "..." + ">"
class Memory(object):
def __init__(self, process_handle, target):
self._process_handle = process_handle
self._target = target
self.found = []
self.__scann_process()
def __scann_process(self):
"""scans a processes pages for the target value."""
si = SYSTEM_INFO()
psi = byref(si)
windll.kernel32.GetSystemInfo(psi)
base_address = si.lpMinimumApplicationAddress
max_address = si.lpMaximumApplicationAddress
page_address = base_address
while page_address < max_address:
page_address = self.__scan_page(page_address)
if len(self.found) >= 60000000:
print("[Warning] Scan ended early because too many addresses were found to hold the target data.")
break
gc.collect()
return self.found
def __scan_page(self, page_address):
"""Scans the entire page for TARGET instance and returns the next page address and found addresses."""
information = self.VirtualQueryEx(page_address)
base_address = information.BaseAddress
region_size = information.RegionSize
next_region = base_address + region_size
size = self._target.size
target_value = self._target.value
step = self._target.alignment
unpacker = self._target.packer.unpack
if information.Type != "MEM_PRIVATE" or \
region_size < size or \
information.State != "MEM_COMMIT" or \
information.Protect not in ["PAGE_EXECUTE_READ", "PAGEEXECUTE_READWRITE", "PAGE_READWRITE"]:
return next_region
page_bytes = self.ReadMemory(base_address, region_size)
for i in xrange(0, (region_size - size), step):
partial = page_bytes[i:i + size]
if unpacker(partial)[0] == target_value:
self.found.append(base_address + i)
del page_bytes # free the buffer
return next_region
def ReadMemory(self, address, size):
cbuffer = c_buffer(size)
success = windll.kernel32.ReadProcessMemory(
self._process_handle,
address,
cbuffer,
size,
0)
assert success, "ReadMemory Failed with success == %s and address == %s and size == %s.\n%s" % (
success, address, size, WinError(win32api.GetLastError()))
return cbuffer.raw
def VirtualQueryEx(self, address):
MBI = MEMORY_BASIC_INFORMATION()
MBI_pointer = byref(MBI)
size = sizeof(MBI)
success = windll.kernel32.VirtualQueryEx(
self._process_handle,
address,
MBI_pointer,
size)
assert success, "VirtualQueryEx Failed with success == %s.\n%s" % (
success, WinError(win32api.GetLastError())[1])
assert success == size, "VirtualQueryEx Failed because not all data was written."
return PyMEMORY_BASIC_INFORMATION(MBI)
def AdjustPrivilege(priv):
flags = win32security.TOKEN_ADJUST_PRIVILEGES | win32security.TOKEN_QUERY
p = win32api.GetCurrentProcess()
htoken = win32security.OpenProcessToken(p, flags)
id = win32security.LookupPrivilegeValue(None, priv)
newPrivileges = [(id, win32security.SE_PRIVILEGE_ENABLED)]
win32security.AdjustTokenPrivileges(htoken, 0, newPrivileges)
win32api.CloseHandle(htoken)
def OpenProcess(pid=win32api.GetCurrentProcessId()):
# ntsecuritycon.SE_DEBUG_NAME = "SeDebugPrivilege"
AdjustPrivilege(ntsecuritycon.SE_DEBUG_NAME)
phandle = windll.kernel32.OpenProcess( \
PROCESS_ALL_ACCESS,
0,
pid)
assert phandle, "Failed to open process!\n%s" % WinError(win32api.GetLastError())[1]
return phandle
PID = 22852
process_handle = OpenProcess(PID)
Memory(process_handle, TARGET(create_string_buffer("1456")))
Here is the error I always get;
AssertionError: ReadMemory Failed with success == 0 and address == 131072 and size == 4096.
[Error 5] Access is denied.
I do not know what information else about my code and my personal Windows 7 operating system, I should provide to you. If you need to know more, please ask it from me, I will provide it to solve that problem.
I guess, this is about a lack of configuration in my operating system , not about pywin32. I'll be waiting for your solutions.

Resources