Windows에서 다른 프로세스의 메모리를 변경하기 위해 Perl, Python 또는 Ruby 프로그램을 작성하는 방법은 무엇입니까?

StackOverflow https://stackoverflow.com/questions/1013828

문제

Perl, Python 또는 Ruby가 프로그램을 작성하여 다른 프로세스 (아마도 데이터 및 코드 데이터 모두에 대한 힙)에서 0x12345678을 찾을 수 있도록 프로그램을 작성하는 데 사용될 수 있는지 궁금합니다. 0x00000000으로? 그것은 비슷한 것입니다 치트 엔진, 창에서 그런 일을 할 수 있습니다.

도움이 되었습니까?

해결책

처음에는 이것이 불가능하다고 생각했지만 Brian의 의견을 본 후 CPAN과 LO를 검색하고 보라. Win32 :: 프로세스 :: 메모리:

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

모듈은 분명히 사용합니다 ReadProcessMemory 기능 : 여기 내 시도 중 하나가 있습니다.

#!/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 }

산출:

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

다른 팁

프로그램을 프로세스에 디버거로 첨부 한 경우, 적절한 API 주변의 래퍼가 존재하는 경우 해당 언어로 또는 CTYPES (Python)와 같은 것을 통해 Windows 기능에 직접 액세스하여 가능해야합니다. 그러나 높은 수준의 언어에서는 하이 레벨 데이터 유형을 낮은 데이터 유형으로 변환하는 방법에 관심을 가져야하므로보다 낮은 수준의 언어로 수행하는 것이 더 쉽습니다.

전화하여 시작하십시오 개방 처리 디버깅 프로세스에서 적절한 액세스가 요청되면 (기계의 관리자 여야합니다 / 액세스를 얻기 위해 상당히 높은 권한이 있어야합니다). 그런 다음 같은 기능을 호출 할 수 있어야합니다 readprocessmemory 그리고 WriteProcessMemory 그 과정의 기억을 읽고 쓰는 것.

편집하다 다음은 다른 프로세스의 주소 공간에서 메모리를 성공적으로 읽는 기능의 빠른 파이썬 개념 증명입니다.

import ctypes
import ctypes.wintypes
kernel32 = ctypes.wintypes.windll.kernel32

# Various access flag definitions:
class Access:
    DELETE      = 0x00010000
    READ_CONTROL= 0x00020000
    SYNCHRONIZE = 0x00100000
    WRITE_DAC   = 0x00040000
    WRITE_OWNER = 0x00080000
    PROCESS_VM_WRITE = 0x0020
    PROCESS_VM_READ = 0x0010
    PROCESS_VM_OPERATION = 0x0008
    PROCESS_TERMINATE = 0x0001
    PROCESS_SUSPEND_RESUME = 0x0800
    PROCESS_SET_QUOTA = 0x0100
    PROCESS_SET_INFORMATION = 0x0200
    PROCESS_QUERY_LIMITED_INFORMATION = 0x1000
    PROCESS_QUERY_INFORMATION = 0x0400
    PROCESS_DUP_HANDLE = 0x0040
    PROCESS_CREATE_THREAD = 0x0002
    PROCESS_CREATE_PROCESS = 0x0080

def read_process_mem(pid, address, size):
    """Read memory of the specified process ID."""
    buf = ctypes.create_string_buffer(size)
    gotBytes = ctypes.c_ulong(0)
    h = kernel32.OpenProcess(Access.PROCESS_VM_READ, False, pid)
    try:
        if kernel32.ReadProcessMemory(h, address, buf, size, ctypes.byref(gotBytes)):
            return buf
        else:
            # TODO: report appropriate error GetLastError
            raise Exception("Failed to access process memory.")
    finally:
        kernel32.CloseHandle(h)

물건을 찾으려면 메모리가 어디에 있는지 결정해야합니다. 대부분의 주소 공간이 맵핑되지 않을 것입니다. 프로그램 코드, DLL 등과 같은 것들을 찾을 수있는 표준 오프셋이 있다고 생각했습니다.

재미있는 부분은 다른 프로세스의 메모리에 액세스하는 것입니다. Cheatengine은 메모리 보호를 패배 할 수있는 가상 머신에서 전체 OS를 실행하여이를 수행합니다. 또한 '디버거 아래 실행'모델이 있으며, 일반적으로 권한이 높아진 응용 프로그램 수정의 자식 프로세스로 대상 응용 프로그램을 시작합니다. 참조 Win32 API 그것에 대해 많은 재미있는 것들을 위해.

Perl에서 필요한 액세스가 발생하면 Win32 :: 보안 :: RAW.

프로세스 주입, 지연로드 라이브러리 등을 사용하여이를 수행하는 방법이 있습니다.

나는 당신이 나열된 도구에서 그것을하는 것을 보지 못합니다. 이것은 C와 어셈블러 국가이며 바이러스 작문 영역으로 들어가기 시작했습니다. 일단 작업을 시작하면 바이러스 백신 반 바이러스 패키지가 거부 당하고 시도하고 격리시킵니다. 그래서 당신은 정말로 이것을하고 싶어합니다.

"힘으로 많은 것입니다 ...."

행운을 빕니다

나열된 언어 중 하나에서 전체 프로세스를 구현할 수는 있지만 컴파일 된 언어는 메모리 스캔에 더 좋습니다 (다른 것이없는 경우 속도 고려 사항). Sigscan이라는 DLL (소스 포함)이있어 특정 게임에 맞게 조정 된 상태에서 최소한의 노력으로 귀하의 요구를 적합하도록 수정할 수 있습니다.

Brian의 정답을 바탕으로 DLL을 사용하여 Python 내에서 주소를 얻는 빠르고 더러운 예입니다. 물론 이것은 DLLS 구현과 관련이 있습니다. "모듈 이름"은 일반적으로 치트 엔진에 표시된 DLL 이름입니다. "DLL 및 기호를 열거합니다."대화 상자.

Brian의 모범으로 가이드 라인과 MSDN 자신의 WriteProcessMemory 방법으로 쉽게 확장 할 수 있습니다.

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)

나는 썼다 Proc :: 메모리 그리고 그 기본 도서관 libvas 이 목적을 위해. 그것은 단지 전화합니다 {Read,Write}ProcessMemory Windows의 후드 아래에서 다른 플랫폼도 지원합니다. 예시:

my $mem = Proc::Memory->new(pid => $$); 
$mem->poke(0x12345678, 'L') = 12;
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top