Question: I wonder if Perl, Python, or Ruby can be used to write a program so that it will look for 0x12345678 in the memory of another process (probably the heap, for both data and code data) and then if it is found, change it to 0x00000000? It is something similar to [Cheat Engine](http://www.cheatengine.org/), which can do something like that on Windows.

Answer: 
I initially thought this was not possible but after seeing Brian's comment, I searched CPAN and lo and behold, there is [Win32::Process::Memory](http://search.cpan.org/perldoc/Win32::Process::Memory):

```
C:\> ppm install Win32::Process::Info
C:\> ppm install Win32::Process::Memory

```

The module apparently uses the [`ReadProcessMemory`](http://msdn.microsoft.com/en-us/library/ms680553.aspx) function: Here is one of my attempts:

```
#!/usr/bin/perl
use strict; use warnings;

use Win32;
use Win32::Process;
use Win32::Process::Memory;

my $process;

Win32::Process::Create(
    $process,
    'C:/opt/vim/vim72/gvim.exe',
    q{},
    0,
    NORMAL_PRIORITY_CLASS,
    q{.}
) or die ErrorReport();

my $mem = Win32::Process::Memory->new({
    pid => $process->GetProcessID(),
    access => 'read/query',
});

$mem->search_sub( 'VIM', sub {
    print $mem->hexdump($_[0], 0x20), "\n";
});

sub ErrorReport{
    Win32::FormatMessage( Win32::GetLastError() );
}

END { $process->Kill(0) if $process }

```

Output:

```
C:\Temp> proc
0052A580 : 56 49 4D 20 2D 20 56 69 20 49 4D 70 72 6F 76 65 : VIM - Vi IMprove
0052A590 : 64 20 37 2E 32 20 28 32 30 30 38 20 41 75 67 20 : d 7.2 (2008 Aug

0052A5F0 :       56 49 4D 52 55 4E 54 49 4D 45 3A 20 22 00 :   VIMRUNTIME: ".
0052A600 : 20 20 66 61 6C 6C 2D 62 61 63 6B 20 66 6F 72 20 :   fall-back for
0052A610 : 24 56                                           : $V

```
It is possible to implement the entire process in one of the languages listed but a compiled language would be better for memory scanning (speed considerations if nothing else). There is a dll (with source) called SigScan available that, while tailored for a specific game, could probably be modified to suite your needs with minimal effort. 

Building on Brian's correct answer here's a quick and dirty example of using a dll to get your address from within python.
This is, of course, specific to the DLLs implementation. 
"Module name" would generally be the dll name as displayed in Cheat Engines "Enumerate DLLs and Symbols" dialog.

With Brian's example as a guideline and [MSDN](http://msdn.microsoft.com/en-us/library/ms681674%28VS.85%29.aspx "MSDN") you could easily extend this with your own WriteProcessMemory method. 

```
import win32defines
import win32process
import win32gui
from ctypes import *
SigScan = cdll.SigScan
kernel32 = windll.kernel32
addresses = {"Value1" : {"sigArg1" : "b0015ec390518b4c24088d4424005068", 
                          "sigArg2" : 36, 
                          "address" : None,
                          "size"    : 32
                         },
            "Value2" :{"sigArg1" : "3b05XXXXXXXX741285c0",
                          "sigArg2" : None, 
                          "address" : None,
                          "size"    : 32
                        }
        }

def read_process_mem(pid, address, size):
    """Read memory of the specified process ID."""
    buf = create_string_buffer(size)
    gotBytes = c_ulong(0)
    h = kernel32.OpenProcess(win32defines.PROCESS_VM_READ, False, pid)
    try:
        if kernel32.ReadProcessMemory(h, address, buf, size, byref(gotBytes)):
            return buf
        else:
            # TODO: report appropriate error GetLastError
            raise Exception("Failed to access process memory.")
    finally:
        kernel32.CloseHandle(h)
if __name__ == "__main__":
    pid, id = None, None
    ## HWND 
    hwnd = win32gui.FindWindowEx(0, 0, 0, "Window Name here")
    ## pid
    pid = win32process.GetWindowThreadProcessId(hwnd)[-1]
    ## Initialize the sigscan dll
    SigScan.InitializeSigScan(pid, "Module Name")
    ## Find all the addresses registered
    for key in addresses.keys():
        addresses[key]["address"] = SigScan.SigScan(addresses[key]["sigArg1"],
            addresses[key]["sigArg2"])
    ## Allow the scanner to clean up
    SigScan.FinalizeSigScan()
    for key in addresses.keys():
        if addresses[key]["address"] != None:
            print repr(read_process_mem(pid, addresses[key]["address"],
                            addresses[key]["size"]).raw)
```