Unable to read value from memory using offsets - python

I'm trying to extract the value from a memory address using the base address of a .dll + offsets.
I used Cheat Engine to find the base address, and pymem to get the base address as hex.
Here's the code I used to find the base address:
import pymem
pm = pymem.Pymem("PD.exe")
baseAddress = pymem.process.module_from_name(pm.process_handle, "jvm.dll").lpBaseOfDll
print(hex(baseAddress))
#output: 0x51250000
For reading the value I'm using ReadWriteMemory.
from ReadWriteMemory import ReadWriteMemory
rwm = ReadWriteMemory()
process = rwm.get_process_by_id(4372)
process.open()
hp_pointer = process.get_pointer(0x51250000 + 0x0036e654, offsets=[0x28, 0x1d0, 0x26, 0x3a, 0x12])
hp = process.read(hp_pointer)
print(hp)
I used the output from the first code as the base address and added +0036e654 to it, but the output is always 0.
If I replace "jvm.dll" with 51250000 in Cheat Engine the addresses are still calculated correctly.

I was getting it all wrong from the start. The pointer offsets showed in Cheat Engine are hex values, so the offsets should be offsets=[0x40, 0x464, 0x38, 0x58, 0x18].

Related

How to read data from ".data" section of a process?

So, as far as I understand from looking online, the .data section of the PE file contains the static and global variables of the program.
All I am trying to do is create a variable in Python, or write something in notepad.exe, and look it up in its memory using the Win32 API.
What I have done:
I looked into the PE file structure of notepad.exe and found the virtual address of its .data section.
I attached to the running process and found its base address, and then added the virtual address of the .data section to that (is this the right calculation? If not, I would appreciate any learning resources, as I couldn't find much).
I tried to read about 1000 bytes, and I found some data. But when looking for hello (in hex, of course), it didn't find anything.
For the sake of POC and simplicity, I am using the Pymem module to make the Win32 API calls.
Here is my code:
import pymem
import pefile
process = pymem.Pymem('Notepad.exe')
process_module = list(process.list_modules())[0]
pe = pefile.PE(process_module.filename)
data_section = [x for x in pe.sections if b'.data' in x.Name][0]
section_address = process_module.lpBaseOfDll + data_section.VirtualAddress
section_size_to_scan = data_section.section_max_addr - data_section.section_min_addr
mem_dump = process.read_bytes(section_address, section_size_to_scan)
hello_in_hex = b'\x68\x65\x6c\x6c\x6f'
print(mem_dump)
print(hello_in_hex in mem_dump)
Obviously, the output is False.
Does anyone knows where I am making a mistake?

Python Cheats pymem address

in the sample script
import pymem
import pymem.process
import pymem.memory
process = pymem.process
mem = pymem.memory
DMC5 = pymem.Pymem("Game.exe")
DMC5_base = DMC5.process_handle
adress = 0x1F1BFF714C8
value = 99
mem.write_int(DMC5_base, adress, value)
the script works fine without any problems. but if I turn off the game and turn it on again, the address will change and you will have to manually insert a new one into the script. Is there any way to enter static data?
To find a reliable pointer, you need to find a static address, plus offsets, that always points to the address you want. This is a common issue when cheating in games via memory modification. Here's a tutorial on how to do it for Cheat Engine: https://www.solarstrike.net/phpBB3/viewtopic.php?t=65
Here's another tutorial on how to do it with MHS + CE: https://progamercity.net/ghack-tut/229-tutorial-maplestory-finding-pointers-ce-amp-mhs.html
Essentially though, the way it's typically done is via using a debugger to get the address of any code that reads or writes the address, and then introspect the assembly code to determine what addresses and pointers were used to get that address. Then, you take the base address it added the pointer to, and then use the debugger to see what reads that value, and what offsets and pointers it uses. You'll usually have to do this 2-3 times before you'll find a static address.
Once you get the pointer offsets and base address, you would then access that memory address via regular pointer logic. Here's an example of how: How do I look up the value of a multi-level pointer inside a process in Python?
You can also use the ReadWriteMemory module.
For example - here's a Python script that reads and writes the multi-level pointer value from Step 8 of the 32-bit Cheat Engine tutorial:
from ReadWriteMemory import ReadWriteMemory
base_address = 0x00400000 # "Tutorial-i386.exe"
static_address_offset = 0x002426E0 # the offset from the base of the static address of the pointer chain
pointer_static_address = base_address + static_address_offset # "Tutorial-i386.exe" + 2426E0
offsets = [0x0C, 0x14, 0x00, 0x18]
rwm = ReadWriteMemory()
process = rwm.get_process_by_name('Tutorial-i386.exe')
process.open()
my_pointer = process.get_pointer(pointer_static_address, offsets=offsets)
pointer_value = process.read(my_pointer)
print(f'Value: {pointer_value}')
value_to_set = int(input('Enter a value: '))
process.write(my_pointer, value_to_set)
Theres a very big chance you will find the offsets listed on some forum i reccomend googling for the offsets

Best way to design c like struct in python

First of all, I just started python yet I really tried hard to find what fits for me. The thing I am going to do is a simple file system for linux but to tell the truth I don't even sure if it is achievable with python. So I need a bit help of here.
I tried to create a class structure and named tuples (one at a time which one fits) and I decided classes would be better for me. The thing is I couldn't read byte by byte because of the size of my class was 888 while in C it was 44 (I used sys.getsizeof() there) It will be more understand what I want to achieve with some code below
For this structure
struct sb{
int inode_bitmap;
int data_bitmap[10];
};
I used
#SUPER BLOCK
class sb(object):
__slots__ = ['inode_bitmap', 'data_bitmap'] #REDUCE RAM USAGE
def __init__(bruh, inode_bitmap, data_bitmap):
bruh.inode_bitmap = inode_bitmap
bruh.data_bitmap = [None] * 10 #DEFINITION OF ARRAY
Everything was fine till I read it
FILE * fin = fopen("simplefs.bin", "r");
struct inode slash;
fseek(fin, sizeof(struct sb), SEEK_SET);
fread(&slash,sizeof(slash),1,fin);
fin = open("simplefs.bin", "rb")
slash = inode
print("pos:", fin.tell())
contents = fin.read(sys.getsizeof(sb))
print(contents)
Since actual file size was smth like 4800 however when I was reading the size was approximately 318
I am pretty aware that python is not C but I am just doing some experiments if it is achievable
You cannot design a struct and then try to read/write it to the file and expect it to be binary identical. If you want to parse any binary data, you have module struct that allows you to interpret the data you have read as int, float and a dozen of other formats. Still you have to write the formats manually. In your particular case:
import struct
with ('datafile.dat') as fin :
raw_data = fin.read()
data = struct.unpack_from( '11I', raw_data ) # 11 integers
inode_bitmap = data[0]
data_bitmap = data[1:]
Or something along the lines...

trying to call balanceOf function in ethereum using web3.py library but getting error

import json
from web3 import Web3
infura_url = "https://mainnet.infura.io/v3/5b314a9b373442fc8ed0c9cd184e838f"
web3 = Web3(Web3.HTTPProvider(infura_url))
abi=json.loads('[{"constant":true,"inputs":..........] large array')
address = "0xd26114cd6EE289AccF82350c8d8487fedB8A0C07"
contract = web3.eth.contract(address=address, abi=abi)
totalSupply = contract.functions.totalSupply().call()
print(totalSupply)
print(contract.functions.name().call())
print(contract.functions.symbol().call())
balance = contract.functions.balanceOf('0x2551d2357c8da54b7d330917e0e769d33f1f5b93').call()
print(web3.fromWei(balance, 'ether'))
But when I run this code I get this error
web3.exceptions.InvalidAddress: ('Web3.py only accepts checksum
addresses. The software that gave you this non-checksum address should
be considered unsafe, please file it as a bug on their platform. Try
using an ENS name instead. Or, if you must accept lower safety, use
Web3.toChecksumAddress(lower_case_address).',
'0x2551d2357c8da54b7d330917e0e769d33f1f5b93')--> error at this line
Possible solution:
You don't show your Web3 version, at this time fromWei function its outdated and removed from documentation.
contract.functions.balanceOf('0x2551d2357c8da54b7d330917e0e769d33f1f5b93').call()
You got error in above function, because the address you insert isn't a checksum address. If you don't understand what is checksum address, here you have a great explanation, what to do in this case? Obviously you need convert the address you inserted on contract.functions.balanceOf to checksum address.
address2 = Web3.toChecksumAddress('0x2551d2357c8da54b7d330917e0e769d33f1f5b93')
balance=contract.functions.balanceOf(address2).call()
#Don't use fromWei function if its not defined on your Web3 documentation

Accessing a memory-mapped file using Python

I am looking to take use of a memory mapped file from Guild Wars 2, which is designed to link into Mumble for positional audio. The file contains information on the characters coordinates and other useful information.
I have been able to access the coordinate information using this script,
import mmap
import struct
last=[]
while True:
shmem = mmap.mmap(0, 20, "MumbleLink", mmap.ACCESS_READ)
coord=struct.unpack("IL3f", shmem)[2:5]
shmem.close()
if last!=coord:
print(coord)
last = coord
X = coord[2]
Y = coord[0]
Z = coord[1])
My problem is I am having difficulty working out how to get more information out of the file. How would I go about accessing other information that is stored, such as character name and camera position.
There is information on the file here:
https://forum-en.guildwars2.com/forum/community/api/Map-API-Mumble-Mashup
http://mumble.sourceforge.net/Link
Any help would be greatly appreciated.
Cheers,
Ed.
You can try to map more than 20 bytes from the file in mmap call, say use 1024, unpack the whole thing according to the http://mumble.sourceforge.net/Link and then extract the name and camera position:
s = struct.unpack('IL3f3f3f512s3f')
name = s[11].decode('utf-16')
camera_pos_x,camera_pos_y,camera_pos_z = s[12:15]
For the names, create a character name in the game and make sure it gets written to disk - perhaps by exiting the game.
Then use a binary file editor to search for the name. I'm partial to http://sourceforge.net/projects/bpe/ , but there are many of these.
Finding camera positions could prove more difficult. I'd probably start out by finding character names, and then search nearby for things that could be camera positions.

Categories