ctypes-users Mailing List for ctypes
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: Sebastian M. E. <er...@pl...> - 2018-03-21 16:00:28
|
Hi all, I have been working on something, well, a little crazy. It's getting to a pointer where I'd like to actively seek external input from potential users as well as experienced ctypes developers. I hope that this is the right place to look for them. The topic of "somehow" calling a function in a Windows DLL on Linux / OS X / BSD pops up quite frequently. I had to do this many times, which made me develop a number of ugly Python scripts. All of them were using some remote procedure call mechanism between a Unix process and a Wine process. From my perspective, it was the lesser evil compared to writing an full-blown winelib-application around the DLLs. At some point, I decided to consolidate my scripts into a generic Python module, designed as a ctypes drop-in-replacement, hiding all the required plumbing from the user. Meet "zugbruecke": https://github.com/pleiszenburg/zugbruecke If you you're on some Unix-like system and if you have Python and Wine installed, I guess the most simple thing you can do with it is this: import zugbruecke as ctypes dll_pow = ctypes.cdll.msvcrt.pow dll_pow.argtypes = (ctypes.c_double, ctypes.c_double) dll_pow.restype = ctypes.c_double print('You should expect "1024.0" to show up here: "%.1f".' % dll_pow(2.0, 10.0)) You have just witnessed "msvcrt.dll" (Wine's implementation of the MS visual C/C++ runtime library) in action on Unix. Under the hood, zugbruecke automatically spins up a Windows version of Python on top of Wine, which uses the actual ctypes module for calling into the DLL. Subsequently, zugbruecke takes care of shipping arguments and return values back and forth as well as keeping memory in sync. What works: All fundamental data types and pointers to them, structure types, pointers pointing to arbitrary sections of memory (if you can provide a hint on their length) and call back functions / function pointers (with significant limitations, though). What does not work: Plenty of edge cases I probably have not thought of, among "a few" other things. See issue tracker on GitHub. The projects goal is to create a module, which behaves exactly like ctypes would on Windows. Well aware of the limitations of the chosen technical approach, it is intentionally written as a "quick and dirty" solution to a common problem. It is, by no means, meant as a professional alternative to writing a winelib-application, if one heavily relies on a Windows DLL / application on Unix. The current development status is ALPHA and some of the code is of clearly questionable quality. So be careful if you're interesting in actually using the module. I have been using it in production code for numerical applications for a while now, but I also keep verifying and double-checking my results. I'd love to see comments, suggestions, test reports, bug reports or [slating] code reviews. Thanks, Sebastian |
From: Andy N. <ahn...@gm...> - 2018-02-09 09:48:16
|
Dear All, I'm new to ctypes and was wondering if anyone can help me with the following: I have a DLL function as follows: ----------------------------- int __declspec(dllexport) **test1(int ** image_data); int ** test1(int ** image_data) { int i; i=image_data[0][0]; //image_data[0][1] = 7; return image_data; } ------------------------------ and some python code that sends a two dimensional array to it: ------------------------------ from ctypes import * mydll=cdll.LoadLibrary("c:/.../win32project3.dll") mydll.test1.argtypes = [POINTER(POINTER(c_int * 3)*5)] mydll.test1.restype = POINTER(POINTER(c_int * 3)*5) inner_type=c_int*3 array_type=inner_type*5 image_data=array_type(inner_type(1,1,1),inner_type(2,2,2),inner_type(3,3,3),inner_type(4,4,4),inner_type(5,5,5)) pointer_to_array=POINTER(POINTER(c_int*3)*5) pi=cast(image_data,pointer_to_array) pi2=mydll.test1(pi) array=(pi2[0][0][0]) ------------------------------ The program returns an error on the penultimate line of Python and the i=image_data[0][0] line of the DLL: WindowsError: exception: access violation reading 0x000000001 Likewise writing to the array (uncomment the following line) results in the an access violation writing.. error. Any ideas? Many thanks in advance, -- Andy N |
From: Diez B. R. <de...@we...> - 2017-11-23 09:27:39
|
You are trying to use a Windows DLL under Linux. That won’t fly. AFAIK the ft260 shouldn’t need this to begin with, because it’s a HID-device that should show up in your OS. Here is a discussion about using it on Linux: https://www.eevblog.com/forum/microcontrollers/has-anyone-worked-with-the-ftdi-ft260-yet/ <https://www.eevblog.com/forum/microcontrollers/has-anyone-worked-with-the-ftdi-ft260-yet/> Diez > On 23. Nov 2017, at 08:33, Jach Fong <jf...@ms...> wrote: > > Hi! I tried the xml2py under Ubuntu 14.04 on library LibFT260, but fail. > > ubuntu@ubuntu:~/Works$ xml2py -c -d -k defst -l ~/Works/LibFT260.dll -o ~/Works/libft260.py ~/Works/libft260.xml > ... > ... > OSError: /home/ubuntu/Works/LibFT260.dll: invalid ELF header > > Can anyone tell what the problem is? Thank you. > > > Best Regards, > Jach Fong > > PS. this library can be downloaded from the following page: > http://www.ftdichip.com/Products/ICs/FT260.html > > > > --- > This email has been checked for viruses by Avast antivirus software. > https://www.avast.com/antivirus > > > ------------------------------------------------------------------------------ > 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: Jach F. <jf...@ms...> - 2017-11-23 07:33:53
|
Hi! I tried the xml2py under Ubuntu 14.04 on library LibFT260, but fail. ubuntu@ubuntu:~/Works$ xml2py -c -d -k defst -l ~/Works/LibFT260.dll -o ~/Works/libft260.py ~/Works/libft260.xml ... ... OSError: /home/ubuntu/Works/LibFT260.dll: invalid ELF header Can anyone tell what the problem is? Thank you. Best Regards, Jach Fong PS. this library can be downloaded from the following page: http://www.ftdichip.com/Products/ICs/FT260.html --- This email has been checked for viruses by Avast antivirus software. https://www.avast.com/antivirus |
From: Michael C <mys...@gm...> - 2017-10-20 21:59:37
|
Hi all! My project needs to use MEMORY_BASIC_INFORMATION() and SYSTEM_INFO() structures, and previously I thought there wasn't a way (thanks to ErykSun, who wrote it for me, which I have been using) Now I found out someone actually wrote a long time ago, so all I have to do is to download and install it! Now, I installed my numpy with pip install numpy and that worked like a charm but how do I get this? https://stackoverflow.com/questions/21401663/python-windows-api-dump-process-in-buffer-then-regex-search https://github.com/jaimeblasco/Open-Source-Hackers/blob/master/memYara/constants/structures.py Thanks for reading! |
From: Michael C <mys...@gm...> - 2017-10-13 23:10:12
|
Sorry Alan, Steve, everyone Can you take a look of this please? Here is my question about the memory: So I have a base address of a chunk of memory from it's size, from VirtualQueryEx (if you dont use windows, it's ok, it's not about how u get these values, because I think the base concept is the same) start = mbi.BaseAddress finish = mbi.RegionSize So at this time, I use while and this is how it looks like while index < finish: # access the memory here: while memory function( index) # then index += 1, for the inner loop ## this line complete the outer while loop index += mbi.RegionSize so Why did I put down index += 1 ? That's because what I think about the memory looks like this (short)(int)(double)(int)(int)(int)(double) and so on, since I can't predict which address is the beginning of a double, the only way to deal with that is to use increment by 1. Now, from what I have been reading, it seems there is a better way to do it, for instance, a for loop. for(start,finish, 8) why 8? because double begins at exact 0 or multiple of 8 bytes, right? On Thu, Oct 12, 2017 at 6:54 PM, Michael C <mys...@gm...> wrote: > Here is my question about the memory: > > So I have a base address of a chunk of memory from it's size, from > VirtualQueryEx > (if you dont use windows, it's ok, it's not about how u get these values, > because I think > the base concept is the same) > > start = mbi.BaseAddress > finish = mbi.RegionSize > > So at this time, I use while and this is how it looks like > > while index < finish: > # access the memory here: > while memory function( index) > # then index += 1, for the inner loop > > ## this line complete the outer while loop > index += mbi.RegionSize > > > so Why did I put down index += 1 ? > > That's because what I think about the memory looks like this > (short)(int)(double)(int)(int)(int)(double) and so on, > > since I can't predict which address is the beginning of a double, the only > way > to deal with that is to use increment by 1. > > Now, from what I have been reading, it seems there is a better way to do > it, > for instance, a for loop. > > for(start,finish, 8) > > why 8? because double begins at exact 0 or multiple of 8 bytes, right? > > > > On Sun, Oct 8, 2017 at 4:46 PM, Alan Gauld via Tutor <tu...@py...> > wrote: > >> On 08/10/17 20:18, Michael C wrote: >> > This is the red part >> > index = current_address >> > end = current_address + mbi.RegionSize >> > >> > while index < end: >> > if ReadProcessMemory(Process, index, ctypes.byref(buffer), \ >> > ctypes.sizeof(buffer), >> > ctypes.byref(nread)): >> > ## value comparison to be implemented. >> > pass >> > else: >> > raise ctypes.WinError(ctypes.get_last_error()) >> > >> > index += 1 >> >> I haven't been following this closely so may be way off here, >> but does this mean you are incrementing the memory address >> by 1? If so you are only increasing the pointer by 1 byte >> but you are, presumably, reading multiple bytes at a time >> (the size of the buffer presumably). >> >> Do you perhaps need to treat the buffer as a byte array >> and use something like the struct module to decode it? >> (assuming you know what you are reading...?) >> >> But I may be way off, I'm just going on a cursory look. >> >> -- >> Alan G >> Author of the Learn to Program web site >> http://www.alan-g.me.uk/ >> http://www.amazon.com/author/alan_gauld >> Follow my photo-blog on Flickr at: >> http://www.flickr.com/photos/alangauldphotos >> >> >> _______________________________________________ >> Tutor maillist - Tu...@py... >> To unsubscribe or change subscription options: >> https://mail.python.org/mailman/listinfo/tutor >> > > |
From: Michael C <mys...@gm...> - 2017-10-13 01:58:54
|
in fact, when I am using this: end = start + mbi.RegionSize I was getting error from the ReadProcessMemory function, and I couldn't figure it out why. Until I did this: end = current_address + mbi.RegionSize - 7 then it doesn't complain anymore. I think it's because I ran this in a while loop with start += 1 so in the last 7 bytes, I'd be reading past the end of this memory chunk. Is this right? On Thu, Oct 12, 2017 at 6:54 PM, Michael C <mys...@gm...> wrote: > Here is my question about the memory: > > So I have a base address of a chunk of memory from it's size, from > VirtualQueryEx > (if you dont use windows, it's ok, it's not about how u get these values, > because I think > the base concept is the same) > > start = mbi.BaseAddress > finish = mbi.RegionSize > > So at this time, I use while and this is how it looks like > > while index < finish: > # access the memory here: > while memory function( index) > # then index += 1, for the inner loop > > ## this line complete the outer while loop > index += mbi.RegionSize > > > so Why did I put down index += 1 ? > > That's because what I think about the memory looks like this > (short)(int)(double)(int)(int)(int)(double) and so on, > > since I can't predict which address is the beginning of a double, the only > way > to deal with that is to use increment by 1. > > Now, from what I have been reading, it seems there is a better way to do > it, > for instance, a for loop. > > for(start,finish, 8) > > why 8? because double begins at exact 0 or multiple of 8 bytes, right? > > > > On Sun, Oct 8, 2017 at 4:46 PM, Alan Gauld via Tutor <tu...@py...> > wrote: > >> On 08/10/17 20:18, Michael C wrote: >> > This is the red part >> > index = current_address >> > end = current_address + mbi.RegionSize >> > >> > while index < end: >> > if ReadProcessMemory(Process, index, ctypes.byref(buffer), \ >> > ctypes.sizeof(buffer), >> > ctypes.byref(nread)): >> > ## value comparison to be implemented. >> > pass >> > else: >> > raise ctypes.WinError(ctypes.get_last_error()) >> > >> > index += 1 >> >> I haven't been following this closely so may be way off here, >> but does this mean you are incrementing the memory address >> by 1? If so you are only increasing the pointer by 1 byte >> but you are, presumably, reading multiple bytes at a time >> (the size of the buffer presumably). >> >> Do you perhaps need to treat the buffer as a byte array >> and use something like the struct module to decode it? >> (assuming you know what you are reading...?) >> >> But I may be way off, I'm just going on a cursory look. >> >> -- >> Alan G >> Author of the Learn to Program web site >> http://www.alan-g.me.uk/ >> http://www.amazon.com/author/alan_gauld >> Follow my photo-blog on Flickr at: >> http://www.flickr.com/photos/alangauldphotos >> >> >> _______________________________________________ >> Tutor maillist - Tu...@py... >> To unsubscribe or change subscription options: >> https://mail.python.org/mailman/listinfo/tutor >> > > |
From: Michael C <mys...@gm...> - 2017-10-13 01:54:18
|
Here is my question about the memory: So I have a base address of a chunk of memory from it's size, from VirtualQueryEx (if you dont use windows, it's ok, it's not about how u get these values, because I think the base concept is the same) start = mbi.BaseAddress finish = mbi.RegionSize So at this time, I use while and this is how it looks like while index < finish: # access the memory here: while memory function( index) # then index += 1, for the inner loop ## this line complete the outer while loop index += mbi.RegionSize so Why did I put down index += 1 ? That's because what I think about the memory looks like this (short)(int)(double)(int)(int)(int)(double) and so on, since I can't predict which address is the beginning of a double, the only way to deal with that is to use increment by 1. Now, from what I have been reading, it seems there is a better way to do it, for instance, a for loop. for(start,finish, 8) why 8? because double begins at exact 0 or multiple of 8 bytes, right? On Sun, Oct 8, 2017 at 4:46 PM, Alan Gauld via Tutor <tu...@py...> wrote: > On 08/10/17 20:18, Michael C wrote: > > This is the red part > > index = current_address > > end = current_address + mbi.RegionSize > > > > while index < end: > > if ReadProcessMemory(Process, index, ctypes.byref(buffer), \ > > ctypes.sizeof(buffer), > > ctypes.byref(nread)): > > ## value comparison to be implemented. > > pass > > else: > > raise ctypes.WinError(ctypes.get_last_error()) > > > > index += 1 > > I haven't been following this closely so may be way off here, > but does this mean you are incrementing the memory address > by 1? If so you are only increasing the pointer by 1 byte > but you are, presumably, reading multiple bytes at a time > (the size of the buffer presumably). > > Do you perhaps need to treat the buffer as a byte array > and use something like the struct module to decode it? > (assuming you know what you are reading...?) > > But I may be way off, I'm just going on a cursory look. > > -- > Alan G > Author of the Learn to Program web site > http://www.alan-g.me.uk/ > http://www.amazon.com/author/alan_gauld > Follow my photo-blog on Flickr at: > http://www.flickr.com/photos/alangauldphotos > > > _______________________________________________ > Tutor maillist - Tu...@py... > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > |
From: Michael C <mys...@gm...> - 2017-10-08 23:49:38
|
thank for replying, but I am toast, so I'll reply tomorrow, thanks! On Sun, Oct 8, 2017 at 4:46 PM, Alan Gauld via Tutor <tu...@py...> wrote: > On 08/10/17 20:18, Michael C wrote: > > This is the red part > > index = current_address > > end = current_address + mbi.RegionSize > > > > while index < end: > > if ReadProcessMemory(Process, index, ctypes.byref(buffer), \ > > ctypes.sizeof(buffer), > > ctypes.byref(nread)): > > ## value comparison to be implemented. > > pass > > else: > > raise ctypes.WinError(ctypes.get_last_error()) > > > > index += 1 > > I haven't been following this closely so may be way off here, > but does this mean you are incrementing the memory address > by 1? If so you are only increasing the pointer by 1 byte > but you are, presumably, reading multiple bytes at a time > (the size of the buffer presumably). > > Do you perhaps need to treat the buffer as a byte array > and use something like the struct module to decode it? > (assuming you know what you are reading...?) > > But I may be way off, I'm just going on a cursory look. > > -- > Alan G > Author of the Learn to Program web site > http://www.alan-g.me.uk/ > http://www.amazon.com/author/alan_gauld > Follow my photo-blog on Flickr at: > http://www.flickr.com/photos/alangauldphotos > > > _______________________________________________ > Tutor maillist - Tu...@py... > To unsubscribe or change subscription options: > https://mail.python.org/mailman/listinfo/tutor > |
From: Michael C <mys...@gm...> - 2017-10-08 21:19:41
|
My apologies, I 'll make sure my questions more ctypes in the future On Oct 8, 2017 2:15 PM, "Guy Kloss" <guy...@au...> wrote: > Hi all, > > I've seen the majority of posts to this lists has been regarding Windows > problems, and problems with ctypes basics in the first place. > > For those who keep posting these questions (e.g. how do I get a pointer > to a particular variable), just please follow FIRST the ctypes tutorial, > and see if your question can be answered there: > > http://python.net/crew/theller/ctypes/tutorial.html > > If it's a particular Windows problem: Go to some bloody Windows forums, > and ask them about their C API. It's quite tiring to have a very low > signal-to-noise ratio in here due to all the questions from people who > (A) do not want to read but have a problem solved FOR THEM, or (B) that > need ctypes unrelated stuff solved. > > Just my two cents worth. > > Cheers, > > Guy > > ------------------------------------------------------------ > ------------------ > 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: Guy K. <guy...@au...> - 2017-10-08 21:15:17
|
Hi all, I've seen the majority of posts to this lists has been regarding Windows problems, and problems with ctypes basics in the first place. For those who keep posting these questions (e.g. how do I get a pointer to a particular variable), just please follow FIRST the ctypes tutorial, and see if your question can be answered there: http://python.net/crew/theller/ctypes/tutorial.html If it's a particular Windows problem: Go to some bloody Windows forums, and ask them about their C API. It's quite tiring to have a very low signal-to-noise ratio in here due to all the questions from people who (A) do not want to read but have a problem solved FOR THEM, or (B) that need ctypes unrelated stuff solved. Just my two cents worth. Cheers, Guy |
From: Michael C <mys...@gm...> - 2017-10-08 19:47:22
|
I'll explain better when I get on a pc. On Oct 8, 2017 12:18 PM, "Michael C" <mys...@gm...> wrote: > This is the red part > index = current_address > end = current_address + mbi.RegionSize > > while index < end: > if ReadProcessMemory(Process, index, ctypes.byref(buffer), \ > ctypes.sizeof(buffer), > ctypes.byref(nread)): > ## value comparison to be implemented. > pass > else: > raise ctypes.WinError(ctypes.get_last_error()) > > index += 1 > > On Oct 8, 2017 12:16 PM, "Mats Wichmann" <ma...@wi...> wrote: > >> On 10/08/2017 11:20 AM, Michael C wrote: >> > Hi all: >> >> > Now, I know the problem is not with VirtualQueryEx, because if I >> comment out >> > the red part and just run VirtualQueryEx, it would actually skim through >> > all regions >> > without a single error. >> > >> > The red part is the problem. >> >> what red part? colors don't come through mailers that use text-based >> settings. This is an example of what your mail looks like to many of us: >> >> https://mail-archive.com/tu...@py.../msg77570.html >> >> please explain in words. >> > |
From: Michael C <mys...@gm...> - 2017-10-08 19:18:29
|
This is the red part index = current_address end = current_address + mbi.RegionSize while index < end: if ReadProcessMemory(Process, index, ctypes.byref(buffer), \ ctypes.sizeof(buffer), ctypes.byref(nread)): ## value comparison to be implemented. pass else: raise ctypes.WinError(ctypes.get_last_error()) index += 1 On Oct 8, 2017 12:16 PM, "Mats Wichmann" <ma...@wi...> wrote: > On 10/08/2017 11:20 AM, Michael C wrote: > > Hi all: > > > Now, I know the problem is not with VirtualQueryEx, because if I comment > out > > the red part and just run VirtualQueryEx, it would actually skim through > > all regions > > without a single error. > > > > The red part is the problem. > > what red part? colors don't come through mailers that use text-based > settings. This is an example of what your mail looks like to many of us: > > https://mail-archive.com/tu...@py.../msg77570.html > > please explain in words. > |
From: Michael C <mys...@gm...> - 2017-10-08 17:20:20
|
Hi all: I have the following code, and somehow I must have fed the read process Memory incorrectly. what the code does is to check a region of memory to see whether or not it can be scanned. mbi.Protect == PAGE_READWRITE and mbi.State == MEM_COMMIT If this is true,then it proceeds to scan the memory fro current_address to current_address + mbi.RegionSize. However, a strange thing happens: The loop runs twice successfully, and then it pops: raise ctypes.WinError(ctypes.get_last_error()) OSError: [WinError 299] Only part of a ReadProcessMemory or WriteProcessMemory request was completed. Now, I know the problem is not with VirtualQueryEx, because if I comment out the red part and just run VirtualQueryEx, it would actually skim through all regions without a single error. The red part is the problem. I have tried to modify the loop. Somehow, if I use this: index = current_address end = current_address + mbi.RegionSize - 7 Where the end is less by 7, the loop would not pop any error and it would finish the loop What did I do wrong? thanks! >code starts current_address = sysinfo.lpMinimumApplicationAddress end_address = sysinfo.lpMaximumApplicationAddress while current_address < end_address: Kernel32.VirtualQueryEx(Process, \ current_address, ctypes.byref(mbi),ctypes.sizeof(mbi)) if mbi.Protect == PAGE_READWRITE and mbi.State == MEM_COMMIT : print('This region can be scanned!') index = current_address end = current_address + mbi.RegionSize while index < end: if ReadProcessMemory(Process, index, ctypes.byref(buffer), \ ctypes.sizeof(buffer), ctypes.byref(nread)): ## value comparison to be implemented. pass else: raise ctypes.WinError(ctypes.get_last_error()) index += 1 current_address += mbi.RegionSize |
From: Michael C <mys...@gm...> - 2017-10-07 21:10:48
|
Or to put it better, I think, it's How do I set up ReadProcessMemory, so that it returns a double instead of 129819721. On Sat, Oct 7, 2017 at 2:00 PM, Michael C <mys...@gm...> wrote: > Hi all: > > I am working on a memory scanner, and the source code and output is as > following: > > Now, I know why my buffer from read process memory looks like values such > as "67108864" ; it's because I read into the buffer entire chunk of memory > at a time, because I fed read process memory this: "mbi.RegionSize" > > Now, how do I read for values such as doubles? > I am guessing I need to use a for loop to scan for small bits of memory > chunk > at a time. > > Is there a way to do it? > > Thanks! > > > > > >output starts > > buffer is: c_ulong(0) > buffer is: c_ulong(0) > buffer is: c_ulong(6385664) > buffer is: c_ulong(67108864) > buffer is: c_ulong(7761920) > buffer is: c_ulong(7798784) > buffer is: c_ulong(7872512) > buffer is: c_ulong(8007680) > buffer is: c_ulong(8044544) > buffer is: c_ulong(8069120) > buffer is: c_ulong(8216576) > buffer is: c_ulong(0) > buffer is: c_ulong(0) > buffer is: c_ulong(3976) > buffer is: c_ulong(0) > buffer is: c_ulong(0) > buffer is: c_ulong(1318755581) > buffer is: c_ulong(0) > buffer is: c_ulong(0) > buffer is: c_ulong(0) > buffer is: c_ulong(0) > > > code starts > > buffer = ctypes.c_uint() > nread = SIZE_T() > > start = ctypes.c_void_p(mbi.BaseAddress) > > ReadProcessMemory = Kernel32.ReadProcessMemory > > MEM_COMMIT = 0x00001000; > PAGE_READWRITE = 0x04; > > current_address = sysinfo.lpMinimumApplicationAddress > end_address = sysinfo.lpMaximumApplicationAddress > > while current_address < end_address: > Kernel32.VirtualQueryEx(Process, \ > current_address, ctypes.byref(mbi),ctypes.sizeof(mbi)) > > if mbi.Protect == PAGE_READWRITE and mbi.State == MEM_COMMIT : > > if ReadProcessMemory(Process, current_address, > ctypes.byref(buffer), \ > ctypes.sizeof(buffer), ctypes.byref(nread)): > print('buffer is: ',buffer) > else: > raise ctypes.WinError(ctypes.get_last_error()) > > current_address += mbi.RegionSize > > |
From: Michael C <mys...@gm...> - 2017-10-07 21:00:33
|
Hi all: I am working on a memory scanner, and the source code and output is as following: Now, I know why my buffer from read process memory looks like values such as "67108864" ; it's because I read into the buffer entire chunk of memory at a time, because I fed read process memory this: "mbi.RegionSize" Now, how do I read for values such as doubles? I am guessing I need to use a for loop to scan for small bits of memory chunk at a time. Is there a way to do it? Thanks! >output starts buffer is: c_ulong(0) buffer is: c_ulong(0) buffer is: c_ulong(6385664) buffer is: c_ulong(67108864) buffer is: c_ulong(7761920) buffer is: c_ulong(7798784) buffer is: c_ulong(7872512) buffer is: c_ulong(8007680) buffer is: c_ulong(8044544) buffer is: c_ulong(8069120) buffer is: c_ulong(8216576) buffer is: c_ulong(0) buffer is: c_ulong(0) buffer is: c_ulong(3976) buffer is: c_ulong(0) buffer is: c_ulong(0) buffer is: c_ulong(1318755581) buffer is: c_ulong(0) buffer is: c_ulong(0) buffer is: c_ulong(0) buffer is: c_ulong(0) > code starts buffer = ctypes.c_uint() nread = SIZE_T() start = ctypes.c_void_p(mbi.BaseAddress) ReadProcessMemory = Kernel32.ReadProcessMemory MEM_COMMIT = 0x00001000; PAGE_READWRITE = 0x04; current_address = sysinfo.lpMinimumApplicationAddress end_address = sysinfo.lpMaximumApplicationAddress while current_address < end_address: Kernel32.VirtualQueryEx(Process, \ current_address, ctypes.byref(mbi),ctypes.sizeof(mbi)) if mbi.Protect == PAGE_READWRITE and mbi.State == MEM_COMMIT : if ReadProcessMemory(Process, current_address, ctypes.byref(buffer), \ ctypes.sizeof(buffer), ctypes.byref(nread)): print('buffer is: ',buffer) else: raise ctypes.WinError(ctypes.get_last_error()) current_address += mbi.RegionSize |
From: Michael C <mys...@gm...> - 2017-10-06 22:36:31
|
I think I pieced together what you have been helping me with, but this still raise a error I have been loosely following this guide: https://www.codeproject.com/articles/716227/csharp-how-to-scan-a-process-memory >code start. 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 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) 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)) print(sysinfo.lpMinimumApplicationAddress) print(sysinfo.lpMaximumApplicationAddress) # maybe it will change, maybe it won't. Assuming it won't. # 2nd, get Open process. PID = 1234 PROCESS_QUERY_INFORMATION = 0x0400 PROCESS_VM_READ = 0x0010 Process = Kernel32.OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_VM_READ, False, PID) print('process:', Process) # 3rd 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) mbi = MEMORY_BASIC_INFORMATION() ##sysinfo.lpMinimumApplicationAddress print('VirtualQueryEx ran properly?',Kernel32.VirtualQueryEx(Process, \ None, ctypes.byref(mbi),ctypes.sizeof(mbi))) # sysinfo.lpMinimumApplicationAddress replaced by None print('') print('mbi start') print('mbi.BaseAddress: ',mbi.BaseAddress) print('mbi.AllocationBase: ',mbi.AllocationBase) print('mbi.AllocationProtect: ',mbi.AllocationProtect) print('mbi.RegionSize: ',mbi.RegionSize) print('mbi.State: ',mbi.State) print('mbi.Protect: ', mbi.Protect) print('mbi.Type: ',mbi.Type) buffer = ctypes.create_string_buffer(mbi.RegionSize) nread = SIZE_T() start = ctypes.c_void_p(mbi.BaseAddress) ##start_pointer = ctypes.byref(start) ReadProcessMemory = Kernel32.ReadProcessMemory if ReadProcessMemory(Process, start, ctypes.byref(buffer), \ ctypes.sizeof(buffer), ctypes.byref(nread)): print('buffer is: ',buffer) else: raise ctypes.WinError(ctypes.get_last_error()) # once I figure out read process memory, I'll combine it with virtual process memory. # if they don't equal to that, then it's time to move to the next thing? # Don't do read memory yet. # make it traverse through all memory and print out when protect and state # are both true. ## ##MEM_COMMIT = 0x00001000; ##PAGE_READWRITE = 0x04; ## ##current_address = sysinfo.lpMinimumApplicationAddress ##end_address = sysinfo.lpMaximumApplicationAddress ## ##while current_address < end_address: ## Kernel32.VirtualQueryEx(Process, \ ## current_address, ctypes.byref(mbi),ctypes.sizeof(mbi)) ## ## if mbi.Protect == PAGE_READWRITE and mbi.State == MEM_COMMIT : ## print(current_address) ## print('Both are true') ## ## ## current_address += mbi.RegionSize On Fri, Oct 6, 2017 at 3:29 PM, eryk sun <er...@gm...> wrote: > On Fri, Oct 6, 2017 at 11:05 PM, Michael C > <mys...@gm...> wrote: > > For this read process memory, if I am trying compose a LPCVOID > > lpBaseAddress, am I not making a variable that equals to > mbi.BaseAddress, > > and then making a pointer pointing to it? > > > > start_address = mbi.BaseAddress > > LPCVOID = ctypes.byref(start_address) > > LPCVOID is a pointer type; don't use it as a variable name because > it's confusing to someone who's reading your code. > > The `BaseAddress` field is an LPVOID, which is an alias for > ctypes.c_void_p. Simple C types such as c_void_p are automatically > converted to Python native types such as int, bytes, and str. It's > fine that mbi.BaseAddress is a Python int. With argtypes defined for > ReadProcessMemory, ctypes will convert the int back to a void pointer > for you automatically. > |
From: eryk s. <er...@gm...> - 2017-10-06 22:30:24
|
On Fri, Oct 6, 2017 at 11:05 PM, Michael C <mys...@gm...> wrote: > For this read process memory, if I am trying compose a LPCVOID > lpBaseAddress, am I not making a variable that equals to mbi.BaseAddress, > and then making a pointer pointing to it? > > start_address = mbi.BaseAddress > LPCVOID = ctypes.byref(start_address) LPCVOID is a pointer type; don't use it as a variable name because it's confusing to someone who's reading your code. The `BaseAddress` field is an LPVOID, which is an alias for ctypes.c_void_p. Simple C types such as c_void_p are automatically converted to Python native types such as int, bytes, and str. It's fine that mbi.BaseAddress is a Python int. With argtypes defined for ReadProcessMemory, ctypes will convert the int back to a void pointer for you automatically. |
From: Michael C <mys...@gm...> - 2017-10-06 22:05:49
|
For this read process memory, if I am trying compose a LPCVOID lpBaseAddress, am I not making a variable that equals to mbi.BaseAddress, and then making a pointer pointing to it? start_address = mbi.BaseAddress LPCVOID = ctypes.byref(start_address) ? But I get this start = ctypes.byref(mbi.BaseAddress) TypeError: byref() argument must be a ctypes instance, not 'int' On Fri, Oct 6, 2017 at 2:53 PM, eryk sun <er...@gm...> wrote: > On Fri, Oct 6, 2017 at 10:26 PM, Michael C > <mys...@gm...> wrote: > > > > base = mbi.BaseAddress > > buffer = ctypes.c_int32() > > buffer_pointer = ctypes.byref(buffer) > > ReadProcessMemory = Kernel32.ReadProcessMemory > > > > if ReadProcessMemory(Process, base, buffer_pointer, mbi.RegionSize, > None): > > print('buffer is: ',buffer) > > else: > > raise ctypes.WinError(ctypes.get_last_error()) > > If you need to read RegionSize bytes, then you have to allocate a > buffer that's RegionSize bytes: > > buffer = ctypes.create_string_buffer(mbi.RegionSize) > > Or use a smaller buffer and loop until the total number of bytes read > is RegionSize. > > Also, remember to check that the state is MEM_COMMIT. You cannot read > an address range that's free or reserved. It must be committed, i.e. > backed by physical storage. > |
From: eryk s. <er...@gm...> - 2017-10-06 21:54:42
|
On Fri, Oct 6, 2017 at 10:26 PM, Michael C <mys...@gm...> wrote: > > base = mbi.BaseAddress > buffer = ctypes.c_int32() > buffer_pointer = ctypes.byref(buffer) > ReadProcessMemory = Kernel32.ReadProcessMemory > > if ReadProcessMemory(Process, base, buffer_pointer, mbi.RegionSize, None): > print('buffer is: ',buffer) > else: > raise ctypes.WinError(ctypes.get_last_error()) If you need to read RegionSize bytes, then you have to allocate a buffer that's RegionSize bytes: buffer = ctypes.create_string_buffer(mbi.RegionSize) Or use a smaller buffer and loop until the total number of bytes read is RegionSize. Also, remember to check that the state is MEM_COMMIT. You cannot read an address range that's free or reserved. It must be committed, i.e. backed by physical storage. |
From: eryk s. <er...@gm...> - 2017-10-06 21:38:50
|
On Fri, Oct 6, 2017 at 10:06 PM, Michael C <mys...@gm...> wrote: > like this? > > buffer = ctypes.byref(ctypes.create_string_buffer(4)) No, the buffer is the array created by create_string_buffer, which you pass byref(). In the following example I create a `test` buffer that contains "spam", and I use the pseudo-handle from GetCurrentProcess with ReadProcessMemory to read this buffer into a target `buffer`. It's silly to do this in the current process, but it's just an example. import ctypes from ctypes.wintypes import HANDLE, LPVOID kernel32 = ctypes.WinDLL('kernel32', use_last_error=True) SIZE_T = ctypes.c_size_t LPSIZE_T = ctypes.POINTER(SIZE_T) kernel32.GetCurrentProcess.restype = HANDLE kernel32.ReadProcessMemory.argtypes = (HANDLE, LPVOID, LPVOID, SIZE_T, LPSIZE_T) hProcess = kernel32.GetCurrentProcess() test = ctypes.create_string_buffer(b'spam') address = ctypes.addressof(test) buffer = ctypes.create_string_buffer(4) nread = SIZE_T() success = kernel32.ReadProcessMemory(hProcess, address, ctypes.byref(buffer), ctypes.sizeof(buffer), ctypes.byref(nread)) if not success: raise ctypes.WinError(ctypes.get_last_error()) print(buffer[:]) |
From: Michael C <mys...@gm...> - 2017-10-06 21:26:34
|
This is my updated version, it still doesn't work :( base = mbi.BaseAddress buffer = ctypes.c_int32() buffer_pointer = ctypes.byref(buffer) ReadProcessMemory = Kernel32.ReadProcessMemory if ReadProcessMemory(Process, base, buffer_pointer, mbi.RegionSize, None): print('buffer is: ',buffer) else: raise ctypes.WinError(ctypes.get_last_error()) On Fri, Oct 6, 2017 at 2:06 PM, Michael C <mys...@gm...> wrote: > like this? > > buffer = ctypes.byref(ctypes.create_string_buffer(4)) > > On Fri, Oct 6, 2017 at 1:55 PM, eryk sun <er...@gm...> wrote: > >> On Fri, Oct 6, 2017 at 9:12 PM, Michael C >> <mys...@gm...> wrote: >> > >> > How do I create a buffer, or rather, is a buffer just a variable? >> >> A buffer is a block of memory for an I/O operation. For example, if >> you need to read a 4-byte (32-bit) integer at an address in another >> process, the 'buffer' could be ctypes.c_int32(). In general, to read >> an arbitrary-sized block of memory, use ctypes.create_string_buffer() >> to create a char array. >> >> > How do I create a pointer to it? >> >> Pass it byref(). >> >> > print('mbi.State: ',mbi.State) >> >> Check whether mbi.State is MEM_COMMIT before trying to read it. If >> it's MEM_FREE or MEM_RESERVE, then ReadProcessMemory will fail. >> >> > buffer = ctypes.create_string_buffer(4) >> > bufferSize = (ctypes.sizeof(buffer)) >> > >> > ReadProcessMemory = Kernel32.ReadProcessMemory >> > >> > if ReadProcessMemory(Process, ctypes.byref(mbi), buffer, bufferSize, >> None): >> > print('buffer is: ',buffer) >> > else: >> > print('something is wrong') >> >> Don't print "something is wrong". You're capturing the thread's last >> error value, so use it to raise an informative exception. For example: >> >> if not success: >> raise ctypes.WinError(ctypes.get_last_error()) >> > > |
From: Michael C <mys...@gm...> - 2017-10-06 21:06:57
|
like this? buffer = ctypes.byref(ctypes.create_string_buffer(4)) On Fri, Oct 6, 2017 at 1:55 PM, eryk sun <er...@gm...> wrote: > On Fri, Oct 6, 2017 at 9:12 PM, Michael C > <mys...@gm...> wrote: > > > > How do I create a buffer, or rather, is a buffer just a variable? > > A buffer is a block of memory for an I/O operation. For example, if > you need to read a 4-byte (32-bit) integer at an address in another > process, the 'buffer' could be ctypes.c_int32(). In general, to read > an arbitrary-sized block of memory, use ctypes.create_string_buffer() > to create a char array. > > > How do I create a pointer to it? > > Pass it byref(). > > > print('mbi.State: ',mbi.State) > > Check whether mbi.State is MEM_COMMIT before trying to read it. If > it's MEM_FREE or MEM_RESERVE, then ReadProcessMemory will fail. > > > buffer = ctypes.create_string_buffer(4) > > bufferSize = (ctypes.sizeof(buffer)) > > > > ReadProcessMemory = Kernel32.ReadProcessMemory > > > > if ReadProcessMemory(Process, ctypes.byref(mbi), buffer, bufferSize, > None): > > print('buffer is: ',buffer) > > else: > > print('something is wrong') > > Don't print "something is wrong". You're capturing the thread's last > error value, so use it to raise an informative exception. For example: > > if not success: > raise ctypes.WinError(ctypes.get_last_error()) > |
From: eryk s. <er...@gm...> - 2017-10-06 20:56:12
|
On Fri, Oct 6, 2017 at 9:12 PM, Michael C <mys...@gm...> wrote: > > How do I create a buffer, or rather, is a buffer just a variable? A buffer is a block of memory for an I/O operation. For example, if you need to read a 4-byte (32-bit) integer at an address in another process, the 'buffer' could be ctypes.c_int32(). In general, to read an arbitrary-sized block of memory, use ctypes.create_string_buffer() to create a char array. > How do I create a pointer to it? Pass it byref(). > print('mbi.State: ',mbi.State) Check whether mbi.State is MEM_COMMIT before trying to read it. If it's MEM_FREE or MEM_RESERVE, then ReadProcessMemory will fail. > buffer = ctypes.create_string_buffer(4) > bufferSize = (ctypes.sizeof(buffer)) > > ReadProcessMemory = Kernel32.ReadProcessMemory > > if ReadProcessMemory(Process, ctypes.byref(mbi), buffer, bufferSize, None): > print('buffer is: ',buffer) > else: > print('something is wrong') Don't print "something is wrong". You're capturing the thread's last error value, so use it to raise an informative exception. For example: if not success: raise ctypes.WinError(ctypes.get_last_error()) |
From: Michael C <mys...@gm...> - 2017-10-06 20:12:39
|
Hi all: How do I create a buffer, or rather, is a buffer just a variable? How do I create a pointer to it? This code ran fine (thanks to you, Eryk, I now know about how to work VirtualQueryEx work) until when I ran the read process memory part. I think I am not feeding the function properly. Please look at the red part of this code Thanks! >code starts here mbi = MEMORY_BASIC_INFORMATION() sysinfo.lpMinimumApplicationAddress print('VirtualQueryEx ran properly?',Kernel32.VirtualQueryEx(Process, \ sysinfo.lpMinimumApplicationAddress, ctypes.byref(mbi),ctypes.sizeof(mbi))) print('') print('mbi start') print('mbi.BaseAddress: ',mbi.BaseAddress) print('mbi.AllocationBase: ',mbi.AllocationBase) print('mbi.AllocationProtect: ',mbi.AllocationProtect) print('mbi.RegionSize: ',mbi.RegionSize) print('mbi.State: ',mbi.State) print('mbi.Protect: ', mbi.Protect) print('mbi.Type: ',mbi.Type) buffer = ctypes.create_string_buffer(4) bufferSize = (ctypes.sizeof(buffer)) ReadProcessMemory = Kernel32.ReadProcessMemory if ReadProcessMemory(Process, ctypes.byref(mbi), buffer, bufferSize, None): print('buffer is: ',buffer) else: print('something is wrong') On Fri, Oct 6, 2017 at 12:03 PM, eryk sun <er...@gm...> wrote: > 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. > |