# Edit/read/observe memory with pymem and pandas DataFrames
## pip install pdmemedit
### Tested against Windows 10 / Python 3.10 / Anaconda
#### Why not use the best libraries for organizing Big Data to organize Big Data?
```python
# Here is an example
# start a separate Python process and get the pid
from time import sleep
import os
tu = (
6666,
77777554,
"b1abvababubux",
b"b1abvababubux",
"b1abvababubux".encode("utf-16-le"),
)
print(os.getpid())
while True:
print(f"{tu=}\t{id(tu)=}")
for v in tu:
print(f"{v=}\t{id(v)=}")
sleep(5)
# output:
# tu=(6666, 77777554, 'b1abvababubux', b'b1abvababubux', b'b\x001\x00a\x00b\x00v\x00a\x00b\x00a\x00b\x00u\x00b\x00u\x00x\x00') id(tu)=1784089644304
# v=6666 id(v)=1784088602128
# v=77777554 id(v)=1784088604816
# v='b1abvababubux' id(v)=1784089580144
# v=b'b1abvababubux' id(v)=1784089556480
# v=b'b\x001\x00a\x00b\x00v\x00a\x00b\x00a\x00b\x00u\x00b\x00u\x00x\x00' id(v)=1784089244720
```
```python
import pymem
import numpy as np
from pdmemedit import Pdmemory
# pass either pid or filename, but not both
pdme = Pdmemory(
pid=21956, filename=None # pid of the Python process we have just created
)
# memory to DataFrame
pdme.update_region_df(
limitfunction=lambda x: True,
dtypes=(
"S1",
np.int8,
np.uint8,
np.int16,
np.uint16,
np.int32,
np.uint32,
np.int64,
np.uint64,
np.float32,
np.float64,
),
allowed_protections=(
pymem.ressources.structure.MEMORY_PROTECTION.PAGE_EXECUTE_READ,
pymem.ressources.structure.MEMORY_PROTECTION.PAGE_EXECUTE_READWRITE,
pymem.ressources.structure.MEMORY_PROTECTION.PAGE_EXECUTE_WRITECOPY,
# pymem.ressources.structure.MEMORY_PROTECTION.PAGE_NOACCESS,
pymem.ressources.structure.MEMORY_PROTECTION.PAGE_READONLY,
pymem.ressources.structure.MEMORY_PROTECTION.PAGE_READWRITE,
pymem.ressources.structure.MEMORY_PROTECTION.PAGE_WRITECOPY,
pymem.ressources.structure.MEMORY_PROTECTION.PAGE_GUARD,
pymem.ressources.structure.MEMORY_PROTECTION.PAGE_NOCACHE,
pymem.ressources.structure.MEMORY_PROTECTION.PAGE_WRITECOMBINE,
),
)
regiondf = pdme.get_regiondf()
print(regiondf)
```
![](https://github.com/hansalemaos/screenshots/blob/main/memedit/regiondf.png?raw=true)
```python
###################################################################
# Search for a string
# Don't forget to get a memory dump by calling pdme.update_region_df before you search for a string
pdme.search_string("b1abvababubux")
stringresultsdf = pdme.get_searchstringdf()
print(stringresultsdf)
```
![](https://github.com/hansalemaos/screenshots/blob/main/memedit/stringresultsdf.png?raw=true)
```python
###################################################################
# Search for a number
# Don't forget to get a memory dump by calling pdme.update_region_df before you search for a number
pdme.search_number(
numexprquery=f"(a == 77777554)", # numexpr.evaluate string, name of 'a' can't be changed
dtypes=(
np.int8,
np.uint8,
np.int16,
np.uint16,
np.int32,
np.uint32,
np.int64,
np.uint64,
# np.float32,
# np.float64,
),
)
numberresults = pdme.get_searchnumberdf()
print(numberresults)
```
![](https://github.com/hansalemaos/screenshots/blob/main/memedit/numberresults.png?raw=true)
```python
###################################################################
# Call pdme.search_number first, edit the DataFrame (self.numbersearchdf) until it serves your needs
# and call pdme.observe_numbers to see how the value changes
pdme.observe_numbers( # ctrl+c to break
keepcondition="(new >= old)", # numexpr.evaluate string, names of 'new/old' can't be changed
sleep_between_scans=1,
savefolder=None,
printoutputlimit=100,
)
observedvalues = pdme.get_observerdf()
print(observedvalues)
```
![](https://github.com/hansalemaos/screenshots/blob/main/memedit/observedvalues.png?raw=true)
```python
###################################################################
# How to edit the memory
numberresults.ff_write.apply(lambda x: x(99999999)) # Overwrites results with 99999999
stringresultsdf.ff_write_str.apply(
lambda x: x("B")
) # binary/utf-8/utf-16-le... conversation should work automatically - overwrites each single letter
# Output after calling numberresults.ff_write/stringresultsdf.ff_write_str
# tu=(6666, 99999999, 'BBBBBBBBBBBBB', b'BBBBBBBBBBBBB', b'B\x00B\x00B\x00B\x00B\x00B\x00B\x00B\x00B\x00B\x00B\x00B\x00B\x00') id(tu)=1784089644304
# v=6666 id(v)=1784088602128
# v=99999999 id(v)=1784088604816
# v='BBBBBBBBBBBBB' id(v)=1784089580144
# v=b'BBBBBBBBBBBBB' id(v)=1784089556480
# v=b'B\x00B\x00B\x00B\x00B\x00B\x00B\x00B\x00B\x00B\x00B\x00B\x00B\x00' id(v)=1784089244720
```
```python
###################################################################
# Use this with care, and limit the area of interest as much as possible, this method might use a lot of memory and get really slow, since
# it dumps the memory of the whole process and compares every single byte with the last memory dump.
# You can stop recording by pressing Ctrl+C
pdme.record_all_changing_values( # might get very slow and use a lot of memory
limitfunc=lambda x: True,
dtype=np.uint32,
allowed_protections=(
pymem.ressources.structure.MEMORY_PROTECTION.PAGE_EXECUTE_READ,
pymem.ressources.structure.MEMORY_PROTECTION.PAGE_EXECUTE_READWRITE,
pymem.ressources.structure.MEMORY_PROTECTION.PAGE_READWRITE,
pymem.ressources.structure.MEMORY_PROTECTION.PAGE_READONLY,
),
)
pdme.get_differencesdf()
```
Raw data
{
"_id": null,
"home_page": "https://github.com/hansalemaos/pdmemedit",
"name": "pdmemedit",
"maintainer": "",
"docs_url": null,
"requires_python": "",
"maintainer_email": "",
"keywords": "pymem,pandas,assembly,hacking,low-level,cheat engine",
"author": "Johannes Fischer",
"author_email": "<aulasparticularesdealemaosp@gmail.com>",
"download_url": "https://files.pythonhosted.org/packages/28/9e/5528a75ecc44893472ba46e577b2134c652cbdc289e24aae07b779d046f5/pdmemedit-0.10.tar.gz",
"platform": null,
"description": "\r\n# Edit/read/observe memory with pymem and pandas DataFrames\r\n\r\n\r\n\r\n## pip install pdmemedit\r\n\r\n\r\n\r\n### Tested against Windows 10 / Python 3.10 / Anaconda \r\n\r\n\r\n\r\n#### Why not use the best libraries for organizing Big Data to organize Big Data?\r\n\r\n\r\n\r\n```python\r\n\r\n# Here is an example\r\n\r\n# start a separate Python process and get the pid\r\n\r\nfrom time import sleep\r\n\r\nimport os\r\n\r\n\r\n\r\ntu = (\r\n\r\n 6666,\r\n\r\n 77777554,\r\n\r\n \"b1abvababubux\",\r\n\r\n b\"b1abvababubux\",\r\n\r\n \"b1abvababubux\".encode(\"utf-16-le\"),\r\n\r\n)\r\n\r\nprint(os.getpid())\r\n\r\nwhile True:\r\n\r\n print(f\"{tu=}\\t{id(tu)=}\")\r\n\r\n\r\n\r\n for v in tu:\r\n\r\n print(f\"{v=}\\t{id(v)=}\")\r\n\r\n sleep(5)\r\n\r\n\r\n\r\n # output:\r\n\r\n # tu=(6666, 77777554, 'b1abvababubux', b'b1abvababubux', b'b\\x001\\x00a\\x00b\\x00v\\x00a\\x00b\\x00a\\x00b\\x00u\\x00b\\x00u\\x00x\\x00')\tid(tu)=1784089644304\r\n\r\n # v=6666\tid(v)=1784088602128\r\n\r\n # v=77777554\tid(v)=1784088604816\r\n\r\n # v='b1abvababubux'\tid(v)=1784089580144\r\n\r\n # v=b'b1abvababubux'\tid(v)=1784089556480\r\n\r\n # v=b'b\\x001\\x00a\\x00b\\x00v\\x00a\\x00b\\x00a\\x00b\\x00u\\x00b\\x00u\\x00x\\x00'\tid(v)=1784089244720\r\n\r\n\r\n\r\n```\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n```python\r\n\r\nimport pymem\r\n\r\nimport numpy as np\r\n\r\nfrom pdmemedit import Pdmemory\r\n\r\n# pass either pid or filename, but not both\r\n\r\npdme = Pdmemory(\r\n\r\n pid=21956, filename=None # pid of the Python process we have just created\r\n\r\n)\r\n\r\n\r\n\r\n# memory to DataFrame\r\n\r\npdme.update_region_df(\r\n\r\n limitfunction=lambda x: True,\r\n\r\n dtypes=(\r\n\r\n \"S1\",\r\n\r\n np.int8,\r\n\r\n np.uint8,\r\n\r\n np.int16,\r\n\r\n np.uint16,\r\n\r\n np.int32,\r\n\r\n np.uint32,\r\n\r\n np.int64,\r\n\r\n np.uint64,\r\n\r\n np.float32,\r\n\r\n np.float64,\r\n\r\n ),\r\n\r\n allowed_protections=(\r\n\r\n pymem.ressources.structure.MEMORY_PROTECTION.PAGE_EXECUTE_READ,\r\n\r\n pymem.ressources.structure.MEMORY_PROTECTION.PAGE_EXECUTE_READWRITE,\r\n\r\n pymem.ressources.structure.MEMORY_PROTECTION.PAGE_EXECUTE_WRITECOPY,\r\n\r\n # pymem.ressources.structure.MEMORY_PROTECTION.PAGE_NOACCESS,\r\n\r\n pymem.ressources.structure.MEMORY_PROTECTION.PAGE_READONLY,\r\n\r\n pymem.ressources.structure.MEMORY_PROTECTION.PAGE_READWRITE,\r\n\r\n pymem.ressources.structure.MEMORY_PROTECTION.PAGE_WRITECOPY,\r\n\r\n pymem.ressources.structure.MEMORY_PROTECTION.PAGE_GUARD,\r\n\r\n pymem.ressources.structure.MEMORY_PROTECTION.PAGE_NOCACHE,\r\n\r\n pymem.ressources.structure.MEMORY_PROTECTION.PAGE_WRITECOMBINE,\r\n\r\n ),\r\n\r\n)\r\n\r\nregiondf = pdme.get_regiondf()\r\n\r\nprint(regiondf)\r\n\r\n\r\n\r\n```\r\n\r\n![](https://github.com/hansalemaos/screenshots/blob/main/memedit/regiondf.png?raw=true)\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n```python\r\n\r\n\r\n\r\n###################################################################\r\n\r\n# Search for a string\r\n\r\n# Don't forget to get a memory dump by calling pdme.update_region_df before you search for a string\r\n\r\npdme.search_string(\"b1abvababubux\")\r\n\r\nstringresultsdf = pdme.get_searchstringdf()\r\n\r\nprint(stringresultsdf)\r\n\r\n```\r\n\r\n![](https://github.com/hansalemaos/screenshots/blob/main/memedit/stringresultsdf.png?raw=true)\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n```python\r\n\r\n###################################################################\r\n\r\n# Search for a number\r\n\r\n# Don't forget to get a memory dump by calling pdme.update_region_df before you search for a number\r\n\r\npdme.search_number(\r\n\r\n numexprquery=f\"(a == 77777554)\", # numexpr.evaluate string, name of 'a' can't be changed\r\n\r\n dtypes=(\r\n\r\n np.int8,\r\n\r\n np.uint8,\r\n\r\n np.int16,\r\n\r\n np.uint16,\r\n\r\n np.int32,\r\n\r\n np.uint32,\r\n\r\n np.int64,\r\n\r\n np.uint64,\r\n\r\n # np.float32,\r\n\r\n # np.float64,\r\n\r\n ),\r\n\r\n)\r\n\r\nnumberresults = pdme.get_searchnumberdf()\r\n\r\nprint(numberresults)\r\n\r\n\r\n\r\n```\r\n\r\n![](https://github.com/hansalemaos/screenshots/blob/main/memedit/numberresults.png?raw=true)\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n```python\r\n\r\n\r\n\r\n###################################################################\r\n\r\n# Call pdme.search_number first, edit the DataFrame (self.numbersearchdf) until it serves your needs\r\n\r\n# and call pdme.observe_numbers to see how the value changes\r\n\r\npdme.observe_numbers( # ctrl+c to break\r\n\r\n keepcondition=\"(new >= old)\", # numexpr.evaluate string, names of 'new/old' can't be changed\r\n\r\n sleep_between_scans=1,\r\n\r\n savefolder=None,\r\n\r\n printoutputlimit=100,\r\n\r\n)\r\n\r\nobservedvalues = pdme.get_observerdf()\r\n\r\nprint(observedvalues)\r\n\r\n\r\n\r\n\r\n\r\n```\r\n\r\n![](https://github.com/hansalemaos/screenshots/blob/main/memedit/observedvalues.png?raw=true)\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n```python\r\n\r\n\r\n\r\n###################################################################\r\n\r\n# How to edit the memory\r\n\r\nnumberresults.ff_write.apply(lambda x: x(99999999)) # Overwrites results with 99999999\r\n\r\nstringresultsdf.ff_write_str.apply(\r\n\r\n lambda x: x(\"B\")\r\n\r\n) # binary/utf-8/utf-16-le... conversation should work automatically - overwrites each single letter\r\n\r\n\r\n\r\n# Output after calling numberresults.ff_write/stringresultsdf.ff_write_str\r\n\r\n# tu=(6666, 99999999, 'BBBBBBBBBBBBB', b'BBBBBBBBBBBBB', b'B\\x00B\\x00B\\x00B\\x00B\\x00B\\x00B\\x00B\\x00B\\x00B\\x00B\\x00B\\x00B\\x00')\tid(tu)=1784089644304\r\n\r\n# v=6666\tid(v)=1784088602128\r\n\r\n# v=99999999\tid(v)=1784088604816\r\n\r\n# v='BBBBBBBBBBBBB'\tid(v)=1784089580144\r\n\r\n# v=b'BBBBBBBBBBBBB'\tid(v)=1784089556480\r\n\r\n# v=b'B\\x00B\\x00B\\x00B\\x00B\\x00B\\x00B\\x00B\\x00B\\x00B\\x00B\\x00B\\x00B\\x00'\tid(v)=1784089244720\r\n\r\n\r\n\r\n\r\n\r\n```\r\n\r\n\r\n\r\n\r\n\r\n```python\r\n\r\n\r\n\r\n\r\n\r\n###################################################################\r\n\r\n\r\n\r\n# Use this with care, and limit the area of interest as much as possible, this method might use a lot of memory and get really slow, since\r\n\r\n# it dumps the memory of the whole process and compares every single byte with the last memory dump.\r\n\r\n# You can stop recording by pressing Ctrl+C\r\n\r\npdme.record_all_changing_values( # might get very slow and use a lot of memory\r\n\r\n limitfunc=lambda x: True,\r\n\r\n dtype=np.uint32,\r\n\r\n allowed_protections=(\r\n\r\n pymem.ressources.structure.MEMORY_PROTECTION.PAGE_EXECUTE_READ,\r\n\r\n pymem.ressources.structure.MEMORY_PROTECTION.PAGE_EXECUTE_READWRITE,\r\n\r\n pymem.ressources.structure.MEMORY_PROTECTION.PAGE_READWRITE,\r\n\r\n pymem.ressources.structure.MEMORY_PROTECTION.PAGE_READONLY,\r\n\r\n ),\r\n\r\n)\r\n\r\npdme.get_differencesdf()\r\n\r\n\r\n\r\n```\r\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Edit/read/observe memory with pymem and pandas",
"version": "0.10",
"split_keywords": [
"pymem",
"pandas",
"assembly",
"hacking",
"low-level",
"cheat engine"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "297553844cf30ce5c519e6aa104563e8e54af83cf9655de3cf5381f9b65f5d8d",
"md5": "586e19a8804c72cd8193c29a8bafd71e",
"sha256": "f55a3d805a623bed96f1ba78c968d0e5a8ffe9c6ee5ccb16eed9c05dea543477"
},
"downloads": -1,
"filename": "pdmemedit-0.10-py3-none-any.whl",
"has_sig": false,
"md5_digest": "586e19a8804c72cd8193c29a8bafd71e",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": null,
"size": 38673,
"upload_time": "2023-03-31T02:53:05",
"upload_time_iso_8601": "2023-03-31T02:53:05.869542Z",
"url": "https://files.pythonhosted.org/packages/29/75/53844cf30ce5c519e6aa104563e8e54af83cf9655de3cf5381f9b65f5d8d/pdmemedit-0.10-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "289e5528a75ecc44893472ba46e577b2134c652cbdc289e24aae07b779d046f5",
"md5": "d6565860e7a08828e47beb620702697d",
"sha256": "e6b7a03056eede644f52eb51e3bc19757d3444c90c8d7c1aa504027008a8367c"
},
"downloads": -1,
"filename": "pdmemedit-0.10.tar.gz",
"has_sig": false,
"md5_digest": "d6565860e7a08828e47beb620702697d",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 38322,
"upload_time": "2023-03-31T02:53:07",
"upload_time_iso_8601": "2023-03-31T02:53:07.867259Z",
"url": "https://files.pythonhosted.org/packages/28/9e/5528a75ecc44893472ba46e577b2134c652cbdc289e24aae07b779d046f5/pdmemedit-0.10.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2023-03-31 02:53:07",
"github": true,
"gitlab": false,
"bitbucket": false,
"github_user": "hansalemaos",
"github_project": "pdmemedit",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"requirements": [],
"lcname": "pdmemedit"
}