ctypes-users Mailing List for ctypes (Page 2)
Brought to you by:
theller
You can subscribe to this list here.
2003 |
Jan
(3) |
Feb
(97) |
Mar
(38) |
Apr
(50) |
May
(68) |
Jun
(67) |
Jul
(184) |
Aug
(58) |
Sep
(30) |
Oct
(40) |
Nov
(41) |
Dec
(53) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2004 |
Jan
(81) |
Feb
(48) |
Mar
(35) |
Apr
(85) |
May
(47) |
Jun
(56) |
Jul
(60) |
Aug
(103) |
Sep
(46) |
Oct
(39) |
Nov
(19) |
Dec
(50) |
2005 |
Jan
(36) |
Feb
(65) |
Mar
(119) |
Apr
(132) |
May
(93) |
Jun
(71) |
Jul
(42) |
Aug
(69) |
Sep
(41) |
Oct
(61) |
Nov
(31) |
Dec
(42) |
2006 |
Jan
(59) |
Feb
(112) |
Mar
(60) |
Apr
(64) |
May
(116) |
Jun
(128) |
Jul
(68) |
Aug
(92) |
Sep
(58) |
Oct
(91) |
Nov
(73) |
Dec
(52) |
2007 |
Jan
(37) |
Feb
(59) |
Mar
(26) |
Apr
(30) |
May
(37) |
Jun
(25) |
Jul
(20) |
Aug
(54) |
Sep
(68) |
Oct
(16) |
Nov
(34) |
Dec
(34) |
2008 |
Jan
(72) |
Feb
(40) |
Mar
(25) |
Apr
(54) |
May
(61) |
Jun
(22) |
Jul
(41) |
Aug
(26) |
Sep
(26) |
Oct
(66) |
Nov
(42) |
Dec
(58) |
2009 |
Jan
(100) |
Feb
(48) |
Mar
(20) |
Apr
(13) |
May
(10) |
Jun
(33) |
Jul
(9) |
Aug
|
Sep
(17) |
Oct
(9) |
Nov
(4) |
Dec
(64) |
2010 |
Jan
(18) |
Feb
(8) |
Mar
(37) |
Apr
(14) |
May
(9) |
Jun
(21) |
Jul
(1) |
Aug
(18) |
Sep
(12) |
Oct
(8) |
Nov
(4) |
Dec
(4) |
2011 |
Jan
(31) |
Feb
(3) |
Mar
(6) |
Apr
(1) |
May
(10) |
Jun
(9) |
Jul
(16) |
Aug
(5) |
Sep
(1) |
Oct
(5) |
Nov
(1) |
Dec
(11) |
2012 |
Jan
(4) |
Feb
(8) |
Mar
(14) |
Apr
(1) |
May
(2) |
Jun
(1) |
Jul
|
Aug
(10) |
Sep
(5) |
Oct
|
Nov
(4) |
Dec
(2) |
2013 |
Jan
(2) |
Feb
|
Mar
(1) |
Apr
|
May
(4) |
Jun
|
Jul
(3) |
Aug
(5) |
Sep
(12) |
Oct
|
Nov
|
Dec
(3) |
2014 |
Jan
|
Feb
|
Mar
|
Apr
(4) |
May
|
Jun
(4) |
Jul
|
Aug
|
Sep
(5) |
Oct
|
Nov
|
Dec
(2) |
2015 |
Jan
|
Feb
|
Mar
(5) |
Apr
|
May
|
Jun
|
Jul
|
Aug
(3) |
Sep
|
Oct
(7) |
Nov
|
Dec
(2) |
2016 |
Jan
(3) |
Feb
(6) |
Mar
(3) |
Apr
|
May
|
Jun
(9) |
Jul
(2) |
Aug
(2) |
Sep
|
Oct
|
Nov
(28) |
Dec
(31) |
2017 |
Jan
|
Feb
|
Mar
|
Apr
(10) |
May
(28) |
Jun
(2) |
Jul
(3) |
Aug
(2) |
Sep
(4) |
Oct
(31) |
Nov
(2) |
Dec
|
2018 |
Jan
|
Feb
(1) |
Mar
(1) |
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: eryk s. <er...@gm...> - 2017-10-06 19:04:36
|
On Fri, Oct 6, 2017 at 7:43 PM, Michael C <mys...@gm...> wrote: > Sorry but I dont understand this line: > > mbi = MEMORY_BASIC_INFORMATION() > > This creates a instance of the class? Yes, and this allocates sizeof(MEMORY_BASIC_INFORMATION) bytes at addressof(mbi), which you pass to a function by reference via byref(mbi). > Also, I thought with VirtualQueryEx, what you need for it > is a handle, which I acquire from this > Process = Kernel32.OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_VM_READ, > False, PID) My example called VirtualQuery, not VirtualQueryEx. Internally VirtualQuery calls VirtualQueryEx using the pseudo handle (HANDLE)(-1), which refers to the current process. > and then feed it to the function like so: > > VirtualQuery(Process, ctypes.byref(mbi), ctypes.sizeof(mbi)) > > I know it doesn't work. But what are these lines for? They don't look like > handle to me: > > VirtualQuery = kernel32.VirtualQuery > VirtualQuery.restype = SIZE_T > VirtualQuery.argtypes = (LPVOID, PMEMORY_BASIC_INFORMATION, SIZE_T) In the above, I'm setting the function pointer's argtypes attribute to the types of the 3 parameters that VirtualQuery takes: the target address (i.e. LPVOID), a pointer to the buffer (i.e. PMEMORY_BASIC_INFORMATION), and the size of the buffer (SIZE_T). This is to allow ctypes to correctly check and convert arguments passed to the function. VirtualQueryEx has four parameters, starting with the handle to the target process, hProcess. The remaining 3 are the same as VirtualQuery. |
From: eryk s. <er...@gm...> - 2017-10-06 18:48:54
|
On Fri, Oct 6, 2017 at 7:26 PM, Michael C <mys...@gm...> wrote: > > I started out with what you gave me: > [...] > > I am trying to acquire "lpMinimumApplicationAddress" and > "lpMaximumApplicationAddress" from system_info, so I did this, > >>code > Kernel32 = ctypes.WinDLL('kernel32', use_last_error=True) > Kernel32.GetSystemInfo(LPSYSTEM_INFO) > print(LPLPSYSTEM_INFO.lpMinimumApplicationAddress) It's the same pattern as before. Create a SYSTEM_INFO instance, which allocates the block of memory for the information, and pass GetSystemInfo a pointer. For example: kernel32 = ctypes.WinDLL('kernel32', use_last_error=True) kernel32.GetSystemInfo.restype = None kernel32.GetSystemInfo.argtypes = (LPSYSTEM_INFO,) sysinfo = SYSTEM_INFO() kernel32.GetSystemInfo(ctypes.byref(sysinfo)) Here are the minimum and maximum addresses for a 64-bit process, formatted in hexadecimal: >>> hex(sysinfo.lpMinimumApplicationAddress) '0x10000' >>> hex(sysinfo.lpMaximumApplicationAddress) '0x7ffffffeffff' |
From: Michael C <mys...@gm...> - 2017-10-06 18:43:11
|
Sorry but I dont understand this line: mbi = MEMORY_BASIC_INFORMATION() This creates a instance of the class? Also, I thought with VirtualQueryEx, what you need for it is a handle, which I acquire from this Process = Kernel32.OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_VM_READ, False, PID) and then feed it to the function like so: VirtualQuery(Process, ctypes.byref(mbi), ctypes.sizeof(mbi)) I know it doesn't work. But what are these lines for? They don't look like handle to me: VirtualQuery = kernel32.VirtualQuery VirtualQuery.restype = SIZE_T VirtualQuery.argtypes = (LPVOID, PMEMORY_BASIC_INFORMATION, SIZE_T) thanks ! On Thu, Oct 5, 2017 at 1:13 PM, eryk sun <er...@gm...> wrote: > On Thu, Oct 5, 2017 at 8:27 PM, Michael C > <mys...@gm...> wrote: > > > > How do I see the values of each field? This doesn't work. > > > > print(PMEMORY_BASIC_INFORMATION.Protect) > > Create an instance of MEMORY_BASIC_INFORMATION and pass a pointer to > it via byref(). For example, the following queries the region of > memory of the VirtualQuery function itself. > > kernel32 = ctypes.WinDLL('kernel32', use_last_error=True) > > MEM_COMMIT = 0x1000 > PAGE_EXECUTE_READ = 0x20 > PAGE_EXECUTE_WRITECOPY = 0x80 > > VirtualQuery = kernel32.VirtualQuery > VirtualQuery.restype = SIZE_T > VirtualQuery.argtypes = (LPVOID, PMEMORY_BASIC_INFORMATION, SIZE_T) > > mbi = MEMORY_BASIC_INFORMATION() > VirtualQuery(VirtualQuery, ctypes.byref(mbi), ctypes.sizeof(mbi)) > > >>> mbi.AllocationBase == kernel32._handle > True > >>> mbi.AllocationProtect == PAGE_EXECUTE_WRITECOPY > True > >>> mbi.BaseAddress > 140703181352960 > >>> mbi.RegionSize > 364544 > >>> mbi.State == MEM_COMMIT > True > >>> mbi.Protect == PAGE_EXECUTE_READ > True > |
From: Michael C <mys...@gm...> - 2017-10-06 18:26:48
|
Hi Eryk Sun: I started out with what you gave me: >code starts class SYSTEM_INFO(ctypes.Structure): """https://msdn.microsoft.com/en-us/library/ms724958""" class _U(ctypes.Union): class _S(ctypes.Structure): _fields_ = (('wProcessorArchitecture', WORD), ('wReserved', WORD)) _fields_ = (('dwOemId', DWORD), # obsolete ('_s', _S)) _anonymous_ = ('_s',) _fields_ = (('_u', _U), ('dwPageSize', DWORD), ('lpMinimumApplicationAddress', LPVOID), ('lpMaximumApplicationAddress', LPVOID), ('dwActiveProcessorMask', DWORD_PTR), ('dwNumberOfProcessors', DWORD), ('dwProcessorType', DWORD), ('dwAllocationGranularity', DWORD), ('wProcessorLevel', WORD), ('wProcessorRevision', WORD)) _anonymous_ = ('_u',) LPSYSTEM_INFO = ctypes.POINTER(SYSTEM_INFO) > code ends I am trying to acquire "lpMinimumApplicationAddress" and "lpMaximumApplicationAddress" from system_info, so I did this, >code Kernel32 = ctypes.WinDLL('kernel32', use_last_error=True) Kernel32.GetSystemInfo(LPSYSTEM_INFO) print(LPLPSYSTEM_INFO.lpMinimumApplicationAddress) >code ends and then it says Traceback (most recent call last): File "C:/Users/AwesomeGuy/Google Drive/My life of hacking/SWTOR/mah scanner/with_eryk_sun_s_help_peace by peace.py", line 55, in <module> Kernel32.GetSystemInfo(LPSYSTEM_INFO) ctypes.ArgumentError: argument 1: <class 'TypeError'>: Don't know how to convert parameter 1 thanks for reading! On Thu, Oct 5, 2017 at 1:13 PM, eryk sun <er...@gm...> wrote: > On Thu, Oct 5, 2017 at 8:27 PM, Michael C > <mys...@gm...> wrote: > > > > How do I see the values of each field? This doesn't work. > > > > print(PMEMORY_BASIC_INFORMATION.Protect) > > Create an instance of MEMORY_BASIC_INFORMATION and pass a pointer to > it via byref(). For example, the following queries the region of > memory of the VirtualQuery function itself. > > kernel32 = ctypes.WinDLL('kernel32', use_last_error=True) > > MEM_COMMIT = 0x1000 > PAGE_EXECUTE_READ = 0x20 > PAGE_EXECUTE_WRITECOPY = 0x80 > > VirtualQuery = kernel32.VirtualQuery > VirtualQuery.restype = SIZE_T > VirtualQuery.argtypes = (LPVOID, PMEMORY_BASIC_INFORMATION, SIZE_T) > > mbi = MEMORY_BASIC_INFORMATION() > VirtualQuery(VirtualQuery, ctypes.byref(mbi), ctypes.sizeof(mbi)) > > >>> mbi.AllocationBase == kernel32._handle > True > >>> mbi.AllocationProtect == PAGE_EXECUTE_WRITECOPY > True > >>> mbi.BaseAddress > 140703181352960 > >>> mbi.RegionSize > 364544 > >>> mbi.State == MEM_COMMIT > True > >>> mbi.Protect == PAGE_EXECUTE_READ > True > |
From: eryk s. <er...@gm...> - 2017-10-05 20:13:59
|
On Thu, Oct 5, 2017 at 8:27 PM, Michael C <mys...@gm...> wrote: > > How do I see the values of each field? This doesn't work. > > print(PMEMORY_BASIC_INFORMATION.Protect) Create an instance of MEMORY_BASIC_INFORMATION and pass a pointer to it via byref(). For example, the following queries the region of memory of the VirtualQuery function itself. kernel32 = ctypes.WinDLL('kernel32', use_last_error=True) MEM_COMMIT = 0x1000 PAGE_EXECUTE_READ = 0x20 PAGE_EXECUTE_WRITECOPY = 0x80 VirtualQuery = kernel32.VirtualQuery VirtualQuery.restype = SIZE_T VirtualQuery.argtypes = (LPVOID, PMEMORY_BASIC_INFORMATION, SIZE_T) mbi = MEMORY_BASIC_INFORMATION() VirtualQuery(VirtualQuery, ctypes.byref(mbi), ctypes.sizeof(mbi)) >>> mbi.AllocationBase == kernel32._handle True >>> mbi.AllocationProtect == PAGE_EXECUTE_WRITECOPY True >>> mbi.BaseAddress 140703181352960 >>> mbi.RegionSize 364544 >>> mbi.State == MEM_COMMIT True >>> mbi.Protect == PAGE_EXECUTE_READ True |
From: Michael C <mys...@gm...> - 2017-10-05 19:34:37
|
Sorry about asking these super obvious little things, I am actually a 1st student, but I acing my programming 101 at the moment lol On Thu, Oct 5, 2017 at 12:27 PM, Michael C <mys...@gm...> wrote: > First of all, thanks for the reply. > > > How do I see the values of each field? This doesn't work. > > print(PMEMORY_BASIC_INFORMATION.Protect) > > thanks! > > On Thu, Oct 5, 2017 at 11:34 AM, eryk sun <er...@gm...> wrote: > >> On Tue, Oct 3, 2017 at 10:30 PM, Michael C >> <mys...@gm...> wrote: >> > >> > I am trying to create SYSTEM_INFO structure and >> MEMORY_BASIC_INFORMATION >> > structure >> >> First, avoid relying on constants, enumerations, and structures >> published on MSDN. It's not always right. Get the SDK and use the >> header files instead. MEMORY_BASIC_INFORMATION is defined in winnt.h, >> and SYSTEM_INFO is defined in sysinfoapi.h. >> >> MEMORY_BASIC_INFORMATION is simple. Don't worry about the >> MEMORY_BASIC_INFORMATION32 and MEMORY_BASIC_INFORMATION64 versions. >> Those are meant for a debugger that's reading this structure directly >> from the memory of another process. >> >> SYSTEM_INFO is a bit tricky, given the anonymous struct and union. I >> prefer to nest the definitions, but you could flatten it as separate >> definitions if you like. Refer to the docs for how to use _anonymous_: >> >> https://docs.python.org/3/library/ctypes#ctypes.Structure._anonymous_ >> >> Here are the definitions. Please don't mindlessly copy and paste. >> Recreate them on your own and use this example as a reference. >> >> import ctypes >> from ctypes.wintypes import WORD, DWORD, LPVOID >> >> PVOID = LPVOID >> SIZE_T = ctypes.c_size_t >> >> # https://msdn.microsoft.com/en-us/library/aa383751#DWORD_PTR >> if ctypes.sizeof(ctypes.c_void_p) == ctypes.sizeof(ctypes.c_ulonglong): >> DWORD_PTR = ctypes.c_ulonglong >> elif ctypes.sizeof(ctypes.c_void_p) == ctypes.sizeof(ctypes.c_ulong): >> DWORD_PTR = ctypes.c_ulong >> >> class MEMORY_BASIC_INFORMATION(ctypes.Structure): >> """https://msdn.microsoft.com/en-us/library/aa366775""" >> _fields_ = (('BaseAddress', PVOID), >> ('AllocationBase', PVOID), >> ('AllocationProtect', DWORD), >> ('RegionSize', SIZE_T), >> ('State', DWORD), >> ('Protect', DWORD), >> ('Type', DWORD)) >> >> PMEMORY_BASIC_INFORMATION = ctypes.POINTER(MEMORY_BASIC_INFORMATION) >> >> class SYSTEM_INFO(ctypes.Structure): >> """https://msdn.microsoft.com/en-us/library/ms724958""" >> class _U(ctypes.Union): >> class _S(ctypes.Structure): >> _fields_ = (('wProcessorArchitecture', WORD), >> ('wReserved', WORD)) >> _fields_ = (('dwOemId', DWORD), # obsolete >> ('_s', _S)) >> _anonymous_ = ('_s',) >> _fields_ = (('_u', _U), >> ('dwPageSize', DWORD), >> ('lpMinimumApplicationAddress', LPVOID), >> ('lpMaximumApplicationAddress', LPVOID), >> ('dwActiveProcessorMask', DWORD_PTR), >> ('dwNumberOfProcessors', DWORD), >> ('dwProcessorType', DWORD), >> ('dwAllocationGranularity', DWORD), >> ('wProcessorLevel', WORD), >> ('wProcessorRevision', WORD)) >> _anonymous_ = ('_u',) >> >> LPSYSTEM_INFO = ctypes.POINTER(SYSTEM_INFO) >> > > |
From: Michael C <mys...@gm...> - 2017-10-05 19:28:00
|
First of all, thanks for the reply. How do I see the values of each field? This doesn't work. print(PMEMORY_BASIC_INFORMATION.Protect) thanks! On Thu, Oct 5, 2017 at 11:34 AM, eryk sun <er...@gm...> wrote: > On Tue, Oct 3, 2017 at 10:30 PM, Michael C > <mys...@gm...> wrote: > > > > I am trying to create SYSTEM_INFO structure and MEMORY_BASIC_INFORMATION > > structure > > First, avoid relying on constants, enumerations, and structures > published on MSDN. It's not always right. Get the SDK and use the > header files instead. MEMORY_BASIC_INFORMATION is defined in winnt.h, > and SYSTEM_INFO is defined in sysinfoapi.h. > > MEMORY_BASIC_INFORMATION is simple. Don't worry about the > MEMORY_BASIC_INFORMATION32 and MEMORY_BASIC_INFORMATION64 versions. > Those are meant for a debugger that's reading this structure directly > from the memory of another process. > > SYSTEM_INFO is a bit tricky, given the anonymous struct and union. I > prefer to nest the definitions, but you could flatten it as separate > definitions if you like. Refer to the docs for how to use _anonymous_: > > https://docs.python.org/3/library/ctypes#ctypes.Structure._anonymous_ > > Here are the definitions. Please don't mindlessly copy and paste. > Recreate them on your own and use this example as a reference. > > import ctypes > from ctypes.wintypes import WORD, DWORD, LPVOID > > PVOID = LPVOID > SIZE_T = ctypes.c_size_t > > # https://msdn.microsoft.com/en-us/library/aa383751#DWORD_PTR > if ctypes.sizeof(ctypes.c_void_p) == ctypes.sizeof(ctypes.c_ulonglong): > DWORD_PTR = ctypes.c_ulonglong > elif ctypes.sizeof(ctypes.c_void_p) == ctypes.sizeof(ctypes.c_ulong): > DWORD_PTR = ctypes.c_ulong > > class MEMORY_BASIC_INFORMATION(ctypes.Structure): > """https://msdn.microsoft.com/en-us/library/aa366775""" > _fields_ = (('BaseAddress', PVOID), > ('AllocationBase', PVOID), > ('AllocationProtect', DWORD), > ('RegionSize', SIZE_T), > ('State', DWORD), > ('Protect', DWORD), > ('Type', DWORD)) > > PMEMORY_BASIC_INFORMATION = ctypes.POINTER(MEMORY_BASIC_INFORMATION) > > class SYSTEM_INFO(ctypes.Structure): > """https://msdn.microsoft.com/en-us/library/ms724958""" > class _U(ctypes.Union): > class _S(ctypes.Structure): > _fields_ = (('wProcessorArchitecture', WORD), > ('wReserved', WORD)) > _fields_ = (('dwOemId', DWORD), # obsolete > ('_s', _S)) > _anonymous_ = ('_s',) > _fields_ = (('_u', _U), > ('dwPageSize', DWORD), > ('lpMinimumApplicationAddress', LPVOID), > ('lpMaximumApplicationAddress', LPVOID), > ('dwActiveProcessorMask', DWORD_PTR), > ('dwNumberOfProcessors', DWORD), > ('dwProcessorType', DWORD), > ('dwAllocationGranularity', DWORD), > ('wProcessorLevel', WORD), > ('wProcessorRevision', WORD)) > _anonymous_ = ('_u',) > > LPSYSTEM_INFO = ctypes.POINTER(SYSTEM_INFO) > |
From: eryk s. <er...@gm...> - 2017-10-05 18:35:07
|
On Tue, Oct 3, 2017 at 10:30 PM, Michael C <mys...@gm...> wrote: > > I am trying to create SYSTEM_INFO structure and MEMORY_BASIC_INFORMATION > structure First, avoid relying on constants, enumerations, and structures published on MSDN. It's not always right. Get the SDK and use the header files instead. MEMORY_BASIC_INFORMATION is defined in winnt.h, and SYSTEM_INFO is defined in sysinfoapi.h. MEMORY_BASIC_INFORMATION is simple. Don't worry about the MEMORY_BASIC_INFORMATION32 and MEMORY_BASIC_INFORMATION64 versions. Those are meant for a debugger that's reading this structure directly from the memory of another process. SYSTEM_INFO is a bit tricky, given the anonymous struct and union. I prefer to nest the definitions, but you could flatten it as separate definitions if you like. Refer to the docs for how to use _anonymous_: https://docs.python.org/3/library/ctypes#ctypes.Structure._anonymous_ Here are the definitions. Please don't mindlessly copy and paste. Recreate them on your own and use this example as a reference. import ctypes from ctypes.wintypes import WORD, DWORD, LPVOID PVOID = LPVOID SIZE_T = ctypes.c_size_t # https://msdn.microsoft.com/en-us/library/aa383751#DWORD_PTR if ctypes.sizeof(ctypes.c_void_p) == ctypes.sizeof(ctypes.c_ulonglong): DWORD_PTR = ctypes.c_ulonglong elif ctypes.sizeof(ctypes.c_void_p) == ctypes.sizeof(ctypes.c_ulong): DWORD_PTR = ctypes.c_ulong class MEMORY_BASIC_INFORMATION(ctypes.Structure): """https://msdn.microsoft.com/en-us/library/aa366775""" _fields_ = (('BaseAddress', PVOID), ('AllocationBase', PVOID), ('AllocationProtect', DWORD), ('RegionSize', SIZE_T), ('State', DWORD), ('Protect', DWORD), ('Type', DWORD)) PMEMORY_BASIC_INFORMATION = ctypes.POINTER(MEMORY_BASIC_INFORMATION) class SYSTEM_INFO(ctypes.Structure): """https://msdn.microsoft.com/en-us/library/ms724958""" class _U(ctypes.Union): class _S(ctypes.Structure): _fields_ = (('wProcessorArchitecture', WORD), ('wReserved', WORD)) _fields_ = (('dwOemId', DWORD), # obsolete ('_s', _S)) _anonymous_ = ('_s',) _fields_ = (('_u', _U), ('dwPageSize', DWORD), ('lpMinimumApplicationAddress', LPVOID), ('lpMaximumApplicationAddress', LPVOID), ('dwActiveProcessorMask', DWORD_PTR), ('dwNumberOfProcessors', DWORD), ('dwProcessorType', DWORD), ('dwAllocationGranularity', DWORD), ('wProcessorLevel', WORD), ('wProcessorRevision', WORD)) _anonymous_ = ('_u',) LPSYSTEM_INFO = ctypes.POINTER(SYSTEM_INFO) |
From: Diez B. R. <de...@we...> - 2017-10-04 12:10:11
|
Haven’t you been shown how to solve similar problems in the past? http://ctypes-users.narkive.com/B30uTrsk/press-esc-to-exit#post3 <http://ctypes-users.narkive.com/B30uTrsk/press-esc-to-exit#post3> What makes this problem different so you can’t follow the recipe of declaring a C-structure as outlined there and in the ctypes documentation? Diez > On 3. Oct 2017, at 21:33, Michael C <mys...@gm...> wrote: > > > Hi all, I am trying to declare a structure, "MEMORY_BASIC_INFORMATION" > > under C++ it's just > > > code > MEMORY_BASIC_INFORMATION mbi; > > code end > > > How do I do that in python? > > Thanks! > ------------------------------------------------------------------------------ > Check out the vibrant tech community on one of the world's most > engaging tech sites, Slashdot.org! http://sdm.link/slashdot_______________________________________________ > ctypes-users mailing list > cty...@li... > https://lists.sourceforge.net/lists/listinfo/ctypes-users |
From: Michael C <mys...@gm...> - 2017-10-03 19:33:14
|
Hi all, I am trying to declare a structure, "MEMORY_BASIC_INFORMATION" under C++ it's just > code MEMORY_BASIC_INFORMATION mbi; > code end How do I do that in python? Thanks! |
From: Michael C <mys...@gm...> - 2017-09-28 00:12:15
|
I am trying to figure out how to extract some information from this game I have! But I have run into a few problems: All this code prints is this line: print('something is wrong') because readprocessmemory isn't working properly, and I have no idea why! Please take a look, thanks! >code starts here import ctypes # setup ctypes. User32 = ctypes.WinDLL('User32', use_last_error=True) Kernel32 = ctypes.WinDLL('kernel32', use_last_error=True) PID = 5924 # or anything other number. PROCESS_QUERY_INFORMATION = 0x0400 PROCESS_VM_READ = 0x0010 Process = Kernel32.OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_VM_READ, False, PID) ReadProcessMemory = Kernel32.ReadProcessMemory # Did I set these up properly? buffer = ctypes.create_string_buffer(4) bufferSize = (ctypes.sizeof(buffer)) # I need a way to find out how big the process is! for n in range(1000000000): if ReadProcessMemory(Process, n, buffer, bufferSize, None): print('buffer is: ',buffer) else: print('something is wrong') print('Done.') |
From: Michael C <mys...@gm...> - 2017-09-25 19:48:14
|
Hi all, I have a few questions about memory scanning! The following code attempts to print out all addresses whose value is int(-143)! 1. I am using a for loop to go through all the addresses! Is this the right thing to do? 2. I feed the read process memory function with hex(i), correct? 3. I am a little bummed by what to put down for my buffer and buffer size, is what I did proper? 4. This is not in the code, but if I actually know the value I want in the memory is a Double, how do i modify my code to look at only doubles? thanks all! > code starts User32 = ctypes.WinDLL('User32', use_last_error=True) Kernel32 = ctypes.WinDLL('kernel32', use_last_error=True) PROCESS_VM_READ = 0x0010 PID = 'given' Process = Kernel32.OpenProcess(PROCESS_VM_READ, 0, PID) ReadProcessMemory = Kernel32.ReadProcessMemory buffer_size = 1000 buffer = ctypes.create_string_buffer(buffer_size) # looking for the addresses where the values are -143, for example # I used 10000000 as an abitrary number, I need to scan the entire application # memory space, but I am not sure how to acquire that value. for i in range(1,10000000): if ReadProcessMemory(Process, hex(i), buffer, buffer_size, None): if float(buffer) == int(-143) : print(float(buffer)) print('Done.') |
From: eryk s. <er...@gm...> - 2017-09-25 07:48:50
|
On Sun, Sep 24, 2017 at 3:08 PM, Michael C <mys...@gm...> wrote: > I tried this, but it returns zero, is it because I need to initiate the > variable, PID, in DWORD, somehow? > > [...] > > PID = 0 > print(User32.GetWindowThreadProcessId(handle, PID)) > print(PID) The second argument, lpdwProcessId, should be a pointer to a DWORD. For example: pid = wintypes.DWORD() tid = user32.GetWindowThreadProcessId(hwnd, ctypes.byref(pid)) print(pid.value) lpdwProcessId is optional, however, and can be NULL if you don't need the process ID. The ctypes equivalent to NULL is passing None. Passing the integer 0, as you did, is undefined behavior, especially with 64-bit Python. The default conversion is to a 32-bit C int, and ctypes doesn't guarantee that the value will be cast to uintptr_t, though recent versions of Python 3 do implement this. There's a chance in Python 2 that the high DWORD will be random garbage, which may cause your program to fail with an access violation. Note that GetWindowThreadProcessId [1] tells a white lie for console applications. A console keeps track of the process and thread ID of every application that's attached to it. You can get the list of attached processes by calling GetConsoleProcessList [2]. Additionally a console stores the process and thread identifiers of its nominal owner as window data at offsets 0 and 4, respectively, which you can query by calling GetWindowLongW. When the window manager sees that you're asking for the owner of a console window, instead of returning the window's *true* owner (i.e. conhost.exe), it returns the console's *nominal* owner. For example: >>> hwnd = kernel32.GetConsoleWindow() >>> con_pid = user32.GetWindowLongW(hwnd, 0) >>> con_tid = user32.GetWindowLongW(hwnd, 4) >>> con_pid, con_tid (3556, 3948) >>> tid = user32.GetWindowThreadProcessId(hwnd, ctypes.byref(pid)) >>> (pid.value, tid) (3556, 3948) Process ID 3556 is the instance of CMD from which I ran Python. In this case, the console only has two attached processes. If I kill CMD, the console will make Python its new nominal owner. For example: Terminate CMD: >>> hp = kernel32.OpenProcess(1, 0, 3556) >>> kernel32.TerminateProcess(hp, 1) 1 Verify that the console promoted my current Python process as its owner: >>> py_pid = kernel32.GetCurrentProcessId() >>> py_tid = kernel32.GetCurrentThreadId() >>> py_pid, py_tid (4888, 3008) >>> con_pid = user32.GetWindowLongW(hwnd, 0) >>> con_tid = user32.GetWindowLongW(hwnd, 4) >>> con_pid, con_tid (4888, 3008) >>> tid = user32.GetWindowThreadProcessId(hwnd, ctypes.byref(pid)) >>> (pid.value, tid) (4888, 3008) [1]: https://msdn.microsoft.com/en-us/library/ms633522 [2]: https://docs.microsoft.com/en-us/windows/console/getconsoleprocesslist |
From: Michael C <mys...@gm...> - 2017-09-24 20:08:41
|
I tried this, but it returns zero, is it because I need to initiate the variable, PID, in DWORD, somehow? thanks! > code import ctypes import os import time User32 = ctypes.WinDLL('User32', use_last_error=True) Kernel32 = ctypes.WinDLL('Kernel32', use_last_error=True) window_name = 'Star Wars™: The Old Republic™' handle = User32.FindWindowW(None, window_name ) print(handle) PID = 0 print(User32.GetWindowThreadProcessId(handle, PID)) print(PID) On Mon, Aug 14, 2017 at 10:07 PM, eryk sun <er...@gm...> wrote: > On Mon, Aug 14, 2017 at 7:57 PM, Michael C > <mys...@gm...> wrote: > > > > I am trying to get the PID of a process given its name. I acquire the > > handle, and then feed it to the ctypes function hoping it would return > the > > PID, but it returns 0! > > > > import ctypes > > > > window_name = 'chrome.exe' > > User32 = ctypes.WinDLL('User32', use_last_error=True) > > Kernel32 = ctypes.WinDLL('Kernel32', use_last_error=True) > > handle = User32.FindWindowW(None, window_name ) > > print(Kernel32.GetProcessId(handle)) > > GetProcessId [1] takes a kernel Process handle, but you're passing it > a user Window handle. Ask the window manager instead. Every Window is > owned by a Thread, and every Thread belongs to a Process. > user32.GetWindowThreadProcessId [2] returns both identifiers. The > second argument to this function is a pointer to a DWORD, to which it > writes the Process ID. > > [1]: https://msdn.microsoft.com/en-us/library/ms683215 > [2]: https://msdn.microsoft.com/en-us/library/ms633522 > |
From: eryk s. <er...@gm...> - 2017-08-15 05:07:54
|
On Mon, Aug 14, 2017 at 7:57 PM, Michael C <mys...@gm...> wrote: > > I am trying to get the PID of a process given its name. I acquire the > handle, and then feed it to the ctypes function hoping it would return the > PID, but it returns 0! > > import ctypes > > window_name = 'chrome.exe' > User32 = ctypes.WinDLL('User32', use_last_error=True) > Kernel32 = ctypes.WinDLL('Kernel32', use_last_error=True) > handle = User32.FindWindowW(None, window_name ) > print(Kernel32.GetProcessId(handle)) GetProcessId [1] takes a kernel Process handle, but you're passing it a user Window handle. Ask the window manager instead. Every Window is owned by a Thread, and every Thread belongs to a Process. user32.GetWindowThreadProcessId [2] returns both identifiers. The second argument to this function is a pointer to a DWORD, to which it writes the Process ID. [1]: https://msdn.microsoft.com/en-us/library/ms683215 [2]: https://msdn.microsoft.com/en-us/library/ms633522 |
From: Michael C <mys...@gm...> - 2017-08-14 19:57:23
|
Hi all: I am trying to get the PID of a process given its name. I acquire the handle, and then feed it to the ctypes function hoping it would return the PID, but it returns 0! import ctypes window_name = 'chrome.exe' User32 = ctypes.WinDLL('User32', use_last_error=True) Kernel32 = ctypes.WinDLL('Kernel32', use_last_error=True) handle = User32.FindWindowW(None, window_name ) print(Kernel32.GetProcessId(handle)) what went wrong? Thanks! |
From: Nan Z. <nan...@gm...> - 2017-07-17 17:42:59
|
Hi Is it possible to modify Ctypes src code locally to support static libraries for Python (the static library is compiled together with Python interpreter)? Since for special reasons, I have to compile everything into one giant Python blob (including Python interpreter, and user Python .py programs(zip section)). Therefore, I cannot use separate .so libraries during my Python blob running. BTW: Python C extension is not considered here, since my clients' code uses Ctypes to bridge there C code for Python. I don't want to change too much in their side. Nan Zhang Best Regards, |
From: Nicolas P. <nic...@aa...> - 2017-07-04 08:52:16
|
Hi, With Python2, you use '/mnt/nor/libpack.so'. With Python3, you use '/mnt/disk/libpack.so'. Does /mnt/disk/libpack.so file exist ? Nicolas Le 04/07/2017 à 09:40, Massimiliano Rosi a écrit : > Hi all, > > My name is Massimiliano, I'm new to the list. > > I have astrange issue on what I cannot find a solution. > > On an ARM arch I need to import a .so library. > > I have installed from source python2.7 and python3.6 > > Now, when I try to import the library on python2 > > Python 2.7.5 (default, Jul 11 2016, 16:11:26) > >>> import ctypes as c > >>> c.__version__ > '1.1.0' > >>> libpack=c.cdll.LoadLibrary('/mnt/nor/libpack.so') > >>> print (libpack.opensocket() > > but on python3 > > Python 3.6.0 (default, Feb 20 2017, 16:41:12) > >>> import ctypes as c > >>> c.__version__ > '1.1.0' > >>> libpack = c.cdll.LoadLibrary('/mnt/disk/libpack.so') > Traceback (most recent call last): > File "<stdin>", line 1, in <module> > File "/mnt/nand/python3.6/lib/python3.6/ctypes/__init__.py", line > 422, in LoadLibrary > return self._dlltype(name) > File "/mnt/nand/python3.6/lib/python3.6/ctypes/__init__.py", line > 344, in __init__ > self._handle = _dlopen(self._name, mode) > OSError: /mnt/disk/libpack.so: undefined symbol: inflateEnd > > I googling to find something about it but nothing put me on the right way. > > Is there anyone that can help me to find a solution? > > Thanks anyone in advance. > > Bye. > > M. > > -- > > */"A parte l'uomo, tutti gli animali sanno che lo scopo principale > della vita è godersela"/* > */Samuel Butler/* > -- > *rosi::LAB di Ro**si Massimiliano* > Mobile: +39 328.3065575 <tel:+39%20328%20306%205575> > Fax: +39 178.2280639 <tel:+39%20178%20228%200639> > E-mail: mas...@gm... <mailto:mas...@gm...> > Pec: mas...@pe... <mailto:mas...@pe...> > Skype: papipano > LinkedIn: Massimiliano Rosi > > ---------------- > "Avvertenze ai sensi del D.Lgs.196 del 30/06/2003 > Le informazioni contenute in questo messaggio di posta elettronica > e/o files allegati, sono da considerarsi strettamente riservati. > Il loro utilizzo è consentito esclusivamente al destinatario del > messaggio, per le finalità indicate nello stesso. > Costituisce violazione ai principi dettati dal D.Lgs. 196/2003: > trattenere il messaggio stesso, divulgarlo anche in parte, distribuirlo > ad altri soggetti, copiarlo o utilizzarlo per finalità diverse. > Qualora riceveste questo messaggio senza esserne il destinatario > Vi preghiamo cortesemente di darcene notizia via e-mail > e di procedere alla distruzione del messaggio stesso, > cancellandolo dal Vostro sistema. > Grazie." > ---------------- > Nota: per proteggere il computer dai virus, le applicazioni di posta > elettronica impediscono l'invio o la ricezione di alcuni tipi di > allegati. Per determinare la modalità di gestione degli allegati, > controllare le impostazioni di protezione della posta elettronica. > > > ------------------------------------------------------------------------------ > Check out the vibrant tech community on one of the world's most > engaging tech sites, Slashdot.org! http://sdm.link/slashdot > > > _______________________________________________ > ctypes-users mailing list > cty...@li... > https://lists.sourceforge.net/lists/listinfo/ctypes-users -- *Nicolas PINAULT R&D electronics engineer *** ni...@aa... <mailto:ni...@aa...> *AATON-Digital* 38000 Grenoble - France Tel +33 4 7642 9550 http://www.aaton.com http://www.transvideo.eu French Technologies for Film and Digital Cinematography Follow us on Twitter @Aaton_Digital @Transvideo_HD Like us on Facebook https://www.facebook.com/AatonDigital |
From: Massimiliano R. <mas...@gm...> - 2017-07-04 07:40:32
|
Hi all, My name is Massimiliano, I'm new to the list. I have astrange issue on what I cannot find a solution. On an ARM arch I need to import a .so library. I have installed from source python2.7 and python3.6 Now, when I try to import the library on python2 Python 2.7.5 (default, Jul 11 2016, 16:11:26) >>> import ctypes as c >>> c.__version__ '1.1.0' >>> libpack=c.cdll.LoadLibrary('/mnt/nor/libpack.so') >>> print (libpack.opensocket() but on python3 Python 3.6.0 (default, Feb 20 2017, 16:41:12) >>> import ctypes as c >>> c.__version__ '1.1.0' >>> libpack = c.cdll.LoadLibrary('/mnt/disk/libpack.so') Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/mnt/nand/python3.6/lib/python3.6/ctypes/__init__.py", line 422, in LoadLibrary return self._dlltype(name) File "/mnt/nand/python3.6/lib/python3.6/ctypes/__init__.py", line 344, in __init__ self._handle = _dlopen(self._name, mode) OSError: /mnt/disk/libpack.so: undefined symbol: inflateEnd I googling to find something about it but nothing put me on the right way. Is there anyone that can help me to find a solution? Thanks anyone in advance. Bye. M. -- *"A parte l'uomo, tutti gli animali sanno che lo scopo principale della vita è godersela"* *Samuel Butler* -- *rosi::LAB di Ro**si Massimiliano* Mobile: +39 328.3065575 <+39%20328%20306%205575> Fax: +39 178.2280639 <+39%20178%20228%200639> E-mail: mas...@gm... Pec: mas...@pe... Skype: papipano LinkedIn: Massimiliano Rosi ---------------- "Avvertenze ai sensi del D.Lgs.196 del 30/06/2003 Le informazioni contenute in questo messaggio di posta elettronica e/o files allegati, sono da considerarsi strettamente riservati. Il loro utilizzo è consentito esclusivamente al destinatario del messaggio, per le finalità indicate nello stesso. Costituisce violazione ai principi dettati dal D.Lgs. 196/2003: trattenere il messaggio stesso, divulgarlo anche in parte, distribuirlo ad altri soggetti, copiarlo o utilizzarlo per finalità diverse. Qualora riceveste questo messaggio senza esserne il destinatario Vi preghiamo cortesemente di darcene notizia via e-mail e di procedere alla distruzione del messaggio stesso, cancellandolo dal Vostro sistema. Grazie." ---------------- Nota: per proteggere il computer dai virus, le applicazioni di posta elettronica impediscono l'invio o la ricezione di alcuni tipi di allegati. Per determinare la modalità di gestione degli allegati, controllare le impostazioni di protezione della posta elettronica. |
From: eryk s. <er...@gm...> - 2017-06-30 04:19:57
|
On Thu, Jun 29, 2017 at 7:31 PM, Sebastian M. Ernst <er...@pl...> wrote: > > the test routine in ctypes.util fails - across multiple Python versions. > I am studying ctypes code to better understand it and found it this way. > The problem occurs in CPython 2.7, 3.4 and 3.6(.1) - I attached two > examples below this email. The error is identical: > OSError: /usr/lib64/libm.so: invalid ELF header libm.so is a linker script that's used when linking an executable or shared library. You can read about it via `man ld` or online. The libm.so script specifies a group consisting of /lib64/libm.so.6, /usr/lib64/libmvec_nonshared.a, and /lib64/libmvec.so.1, with the latter added as an ELF header DT_NEEDED tag only if it sources a required symbol and isn't included already by other needed libraries. The ctypes test is wrong. The runtime loader searches LD_LIBRARY_PATH (if defined), DT_RUNPATH of the executable (if defined), the loader cache file, "/etc/ld.so.cache", and finally the system architecture-specific /lib and /usr/lib. It finds libm.so in /usr/lib64, but the correct library name is libm.so.6 in /lib64. For example: >>> from ctypes.util import find_library >>> find_library('m') 'libm.so.6' >>> find_library('mvec') 'libmvec.so.1' |
From: Sebastian M. E. <er...@pl...> - 2017-06-29 19:44:20
|
Hi all, the test routine in ctypes.util fails - across multiple Python versions. I am studying ctypes code to better understand it and found it this way. The problem occurs in CPython 2.7, 3.4 and 3.6(.1) - I attached two examples below this email. The error is identical: OSError: /usr/lib64/libm.so: invalid ELF header I am running openSUSE Leap 42.2. Looking deeper, my libm.so does not have an ELF header. In my case, it happens to be an ASCII file with the following contents: /* GNU ld script */ OUTPUT_FORMAT(elf64-x86-64) GROUP ( /lib64/libm.so.6 AS_NEEDED ( /usr/lib64/libmvec_nonshared.a /lib64/libmvec.so.1 ) ) I am bit surprised as I have not seen this concept before. For my understanding: Is the (in-)correct handling of ld scripts a bug or simply a missing feature in ctypes? Could it be solved within ctypes (instead of writing workaround code on the application side)? There are some fairly old discussions on ctypes mailing lists, like this one, 14 years old, describing this very behavior: https://sourceforge.net/p/ctypes/mailman/message/4444162/ Thanks, Sebastian -------------------- Python 2.7.13 (default, Mar 22 2017, 12:31:17) [GCC] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> from ctypes import util >>> util.test() libm.so.6 libc.so.6 libbz2.so.1 Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/usr/lib64/python2.7/ctypes/util.py", line 303, in test print cdll.LoadLibrary("libm.so") File "/usr/lib64/python2.7/ctypes/__init__.py", line 440, in LoadLibrary return self._dlltype(name) File "/usr/lib64/python2.7/ctypes/__init__.py", line 362, in __init__ self._handle = _dlopen(self._name, mode) OSError: /usr/lib64/libm.so: invalid ELF header Python 3.4.6 (default, Mar 22 2017, 12:26:13) [GCC] on linux Type "help", "copyright", "credits" or "license" for more information. >>> from ctypes import util >>> util.test() libm.so.6 libc.so.6 libbz2.so.1 Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/usr/lib64/python3.4/ctypes/util.py", line 262, in test print(cdll.LoadLibrary("libm.so")) File "/usr/lib64/python3.4/ctypes/__init__.py", line 429, in LoadLibrary return self._dlltype(name) File "/usr/lib64/python3.4/ctypes/__init__.py", line 351, in __init__ self._handle = _dlopen(self._name, mode) OSError: /usr/lib64/libm.so: invalid ELF header |
From: eryk s. <er...@gm...> - 2017-05-18 20:30:35
|
On Thu, May 18, 2017 at 3:41 PM, Michael C <mys...@gm...> wrote: > Ok, I tried to read > https://msdn.microsoft.com/en-us/library/windows/desktop/ms633573(v=vs.85).aspx > > But it doesn't say which one it belongs to, User32 or Kernel32... I guess > 'User-defined function name' is something I have never seen before, I see > that I should send this to the application: > > #define WM_CLOSE 0x0010 > > But I haven't figured out how. Please read About Messages and Message Queues [1]. Then scan back to the Posting and Sending Messages section. Note that the documentation talks about queued vs nonqueued messages, but under the hood it's really two message queues with different behavior for posted messages vs sent messages. A thread that posts a message to a window via PostMessage doesn't wait for a result from the owning thread. The message gets appended to the posted message queue of the owning thread, which can retrieve it via GetMessage or PeekMessage and dispatch it to the window procedure via DispatchMessage. There's also a PostThreadMessage function that allows posting a message to a thread without specifying a target window. The thread has to handle the message in its message loop since there's no target window and thus no window procedure to which the message can be dispatched. A thread that sends a message to a window via SendMessage waits for a return value, so it has to block on an internal event object that will be signaled after the window's owning thread has processed the message. When the receiving thread checks its message queue (i.e. calls GetMessage, PeekMessage, or WaitMessage), the system automatically dispatches messages from the thread's sent message queue. There are also variants on sending: SendMessageTimeout, SendMessageCallback (use a callback function instead of waiting), and SendNotifyMessage (don't wait when sending to another thread). For example, the following console script closes its console window, thus terminating all processes that are attached to the console: #!/usr/bin/python3 import ctypes from ctypes import wintypes kernel32 = ctypes.WinDLL('kernel32', use_last_error=True) user32 = ctypes.WinDLL('user32', use_last_error=True) WM_CLOSE = 0x0010 def _check_zero(result, func, args): if not result: raise ctypes.WinError(ctypes.get_last_error()) return args kernel32.GetConsoleWindow.errcheck = _check_zero kernel32.GetConsoleWindow.restype = wintypes.HWND user32.PostMessageW.errcheck = _check_zero user32.PostMessageW.argtypes = (wintypes.HWND, wintypes.UINT, wintypes.WPARAM, wintypes.LPARAM) hWnd = kernel32.GetConsoleWindow() user32.PostMessageW(hWnd, WM_CLOSE, 0, 0) [1]: https://msdn.microsoft.com/en-us/library/ms644927 |
From: Michael C <mys...@gm...> - 2017-05-18 15:41:52
|
Ok, I tried to read https://msdn.microsoft.com/en-us/library/windows/desktop/ms633573(v=vs.85).aspx But it doesn't say which one it belongs to, User32 or Kernel32... I guess 'User-defined function name' is something I have never seen before, I see that I should send this to the application: #define WM_CLOSE 0x0010 But I haven't figured out how. thanks! On Wed, May 17, 2017 at 10:03 PM, eryk sun <er...@gm...> wrote: > On Thu, May 18, 2017 at 2:14 AM, Michael C > <mys...@gm...> wrote: > > where can i read up on what a thread is and what it does? > > A book on operating systems would be a good place to start. > > A Thread is a CPU execution context. A Process can and generally will > have multiple threads executing code concurrently. A Process is a like > a container for threads, i.e. the virtual address space and security > context in which they execute (and a Windows Job is a container for > processes, and they're all contained in an NT Session). > > The operating system preemptively dispatches threads to give each a > time slice (quantum) that fairly distributes execution across the > available CPUs based on a combination of thread priority, process > priority, and CPU affinity (i.e. whether the process/thread has been > set to run on a subset of the available CPUs). A CPU context switch to > another thread is expensive, so the scheduler needs to strike a > balance between fairness and performance. > > With all of these threads executing concurrently, it's important to be > able to synchronize their operation. That's where dispatcher > (synchronization) objects come into play -- e.g. timers, events, > mutexes, semaphores, and even threads themselves (i.e. have one thread > wait for another thread to terminate). In Windows a thread can wait on > a dispatcher object using the *WaitFor*Object* family of wait > functions. A waiting thread doesn't get scheduled to execute until the > object its waiting for becomes signaled. However, an alertable wait > can be interrupted by posting an APC routine to the waiting thread's > APC queue, e.g. via QueueUserAPC. > > That said, a thread in Windows is more than just a CPU execution > context. For example, a thread can have an impersonation token to act > on behalf of another user on the system. This feature is typically > used by threads in service processes that are running as LocalSystem > (SYSTEM), LocalService, or NetworkService. That said, it's far more > common for a thread to implicitly operate in the security context of > the primary token of its owning process. > > (The user's access token is created by the Local Security Authority > (LSA) and kernel security reference monitor when the user is logged > on. The access token gets duplicated for every process, which allows > groups and privileges in the token to me enabled and disabled > separately in each process. All copies share the same logon session -- > e.g. for cached network credentials and for the object manager's > per-logon DosDevice directory.) > > Threads also own windows and receive window messages that are > sent/posted to their message queue -- such as WM_CREATE, WM_CLOSE, > WM_DESTROY, WM_QUIT, WM_KEYDOWN, WM_KEYUP, WM_CHAR, WM_HOTKEY, > WM_PAINT, WM_COPY, WM_CUT, WM_PASTE, WM_COPYDATA, WM_TIMER, > WM_SETTINGCHANGE, WM_DEVICECHANGE, WM_POWERBROADCAST, > WM_QUERYENDSESSION, WM_WTSSESSION_CHANGE, etc (way too many to list > them all). > > Also, I/O requests have thread affinity. In this case it's via the > thread's APC (asynchronous procedure call) queue and list of pending > IRPs (I/O request packets). I/O thread affinity is great for a client > application that's requesting I/O, but servers that have to maintain > throughput for thousands of I/O requests need to instead use a pool of > many threads to service requests. In this case I/O thread affinity is > a detriment, which is why Windows has an alternative: I/O completion > ports. When I/O completes via IOCP, it can be handled by the first > available thread in the pool. > > > more importantly, how do i switch to the proper thread? > > That's not something you should do. It may be possible to inject code > into the address space of another process and forcibly cause a given > thread in that process to execute it. But that's a rude thing to do > and would devolve into chaos if everyone wrote code like that. Just > send a WM_CLOSE message to the window. The window manager (implemented > in the win32k.sys kernel module) will send it to the message queue of > the owning thread, which can decide for itself whether it should call > DestroyWindow -- e.g. by asking the user if it's ok to close the > window. > |
From: eryk s. <er...@gm...> - 2017-05-18 05:04:19
|
On Thu, May 18, 2017 at 2:14 AM, Michael C <mys...@gm...> wrote: > where can i read up on what a thread is and what it does? A book on operating systems would be a good place to start. A Thread is a CPU execution context. A Process can and generally will have multiple threads executing code concurrently. A Process is a like a container for threads, i.e. the virtual address space and security context in which they execute (and a Windows Job is a container for processes, and they're all contained in an NT Session). The operating system preemptively dispatches threads to give each a time slice (quantum) that fairly distributes execution across the available CPUs based on a combination of thread priority, process priority, and CPU affinity (i.e. whether the process/thread has been set to run on a subset of the available CPUs). A CPU context switch to another thread is expensive, so the scheduler needs to strike a balance between fairness and performance. With all of these threads executing concurrently, it's important to be able to synchronize their operation. That's where dispatcher (synchronization) objects come into play -- e.g. timers, events, mutexes, semaphores, and even threads themselves (i.e. have one thread wait for another thread to terminate). In Windows a thread can wait on a dispatcher object using the *WaitFor*Object* family of wait functions. A waiting thread doesn't get scheduled to execute until the object its waiting for becomes signaled. However, an alertable wait can be interrupted by posting an APC routine to the waiting thread's APC queue, e.g. via QueueUserAPC. That said, a thread in Windows is more than just a CPU execution context. For example, a thread can have an impersonation token to act on behalf of another user on the system. This feature is typically used by threads in service processes that are running as LocalSystem (SYSTEM), LocalService, or NetworkService. That said, it's far more common for a thread to implicitly operate in the security context of the primary token of its owning process. (The user's access token is created by the Local Security Authority (LSA) and kernel security reference monitor when the user is logged on. The access token gets duplicated for every process, which allows groups and privileges in the token to me enabled and disabled separately in each process. All copies share the same logon session -- e.g. for cached network credentials and for the object manager's per-logon DosDevice directory.) Threads also own windows and receive window messages that are sent/posted to their message queue -- such as WM_CREATE, WM_CLOSE, WM_DESTROY, WM_QUIT, WM_KEYDOWN, WM_KEYUP, WM_CHAR, WM_HOTKEY, WM_PAINT, WM_COPY, WM_CUT, WM_PASTE, WM_COPYDATA, WM_TIMER, WM_SETTINGCHANGE, WM_DEVICECHANGE, WM_POWERBROADCAST, WM_QUERYENDSESSION, WM_WTSSESSION_CHANGE, etc (way too many to list them all). Also, I/O requests have thread affinity. In this case it's via the thread's APC (asynchronous procedure call) queue and list of pending IRPs (I/O request packets). I/O thread affinity is great for a client application that's requesting I/O, but servers that have to maintain throughput for thousands of I/O requests need to instead use a pool of many threads to service requests. In this case I/O thread affinity is a detriment, which is why Windows has an alternative: I/O completion ports. When I/O completes via IOCP, it can be handled by the first available thread in the pool. > more importantly, how do i switch to the proper thread? That's not something you should do. It may be possible to inject code into the address space of another process and forcibly cause a given thread in that process to execute it. But that's a rude thing to do and would devolve into chaos if everyone wrote code like that. Just send a WM_CLOSE message to the window. The window manager (implemented in the win32k.sys kernel module) will send it to the message queue of the owning thread, which can decide for itself whether it should call DestroyWindow -- e.g. by asking the user if it's ok to close the window. |
From: Michael C <mys...@gm...> - 2017-05-18 02:16:57
|
more importantly, how do i switch to the proper thread? thanks! On Wed, May 17, 2017 at 7:14 PM, Michael C <mys...@gm...> wrote: > where can i read up on what a thread is and what it does? > > Thanks! > > On Wed, May 17, 2017 at 7:12 PM, eryk sun <er...@gm...> wrote: > >> On Wed, May 17, 2017 at 11:10 PM, Michael C >> <mys...@gm...> wrote: >> > Apparently even though the MSDN says, given a handle, it would kill the >> > window, but it doesn't do that for me. Am I doing it properly? >> > >> > import time >> > import ctypes >> > User32 = ctypes.WinDLL('User32', use_last_error=True) >> > >> > handle = User32.GetForegroundWindow() >> > print(handle) >> > time.sleep(2) >> > User32.DestroyWindow(handle) >> >> You're not checking the BOOL return value to see whether the call >> succeeded. If it failed, you need to raise an exception for the >> thread's last error value. Do this in a ctypes errcheck function. For >> example: >> >> def _check_bool(result, func, args): >> if not result: >> raise ctypes.WinError(ctypes.get_last_error()) >> return args >> >> User32.DestroyWindow.errcheck = _check_bool >> >> With this check in place, if User32.DestroyWindow(handle) fails, >> you'll get an idiomatic exception. Chances are that the foreground >> window doesn't belong to your thread, and you haven't read the fine >> print in the remarks on MSDN: >> >> A thread cannot use DestroyWindow to destroy a window created by a >> different thread. >> >> Thus it's probably failing with ERROR_ACCESS_DENIED (5). Try sending >> the window a WM_CLOSE message instead. >> > > |