كيف تكتب برنامج Perl أو Python أو Ruby لتغيير ذاكرة عملية أخرى على نظام Windows؟

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

سؤال

أتساءل عما إذا كان من الممكن استخدام Perl أو Python أو Ruby لكتابة برنامج بحيث يبحث عن 0x12345678 في ذاكرة عملية أخرى (ربما الكومة، لكل من البيانات وبيانات التعليمات البرمجية) ثم إذا تم العثور عليه، قم بتغييره إلى 0x00000000؟إنه شيء مشابه ل محرك الغش, ، والتي يمكنها أن تفعل شيئًا كهذا على نظام التشغيل Windows.

هل كانت مفيدة؟

المحلول

واعتقدت في البداية لم يكن ذلك ممكنا ولكن بعد رؤية تعليق براين، لقد بحثت CPAN وها، هناك <لأ href = "http://search.cpan.org/perldoc/Win32::Process::Memory "يختلط =" noreferrer "> 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

نصائح أخرى

من الممكن القيام بذلك إذا قمت بإرفاق برنامجك كمصحح أخطاء إلى العملية، وهو ما يجب أن يكون ممكنًا بهذه اللغات في حالة وجود أغلفة حول واجهات برمجة التطبيقات المناسبة، أو عن طريق الوصول مباشرة إلى وظائف windows من خلال شيء مثل ctypes (لـ python).ومع ذلك، قد يكون من الأسهل القيام بذلك بلغة ذات مستوى منخفض، لأنه في اللغات ذات المستوى الأعلى، سيتعين عليك الاهتمام بكيفية ترجمة أنواع البيانات عالية المستوى إلى أنواع أقل وما إلى ذلك.

ابدأ بالاتصال عملية مفتوحة في عملية تصحيح الأخطاء، مع طلب الوصول المناسب (ستحتاج إلى أن تكون مسؤولاً على الجهاز/تتمتع بامتيازات عالية إلى حد ما لتتمكن من الوصول).يجب أن تكون قادرًا بعد ذلك على استدعاء وظائف مثل قراءة عملية الذاكرة و 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 للحصول على الكثير من وسائل الترفيه حول ذلك.

في بيرل، مرة واحدة كان لديك الوصول إلى المطلوب، وكنت ربما تريد أن تتفاعل معها باستخدام <لأ href = "http://search.cpan.org/~teverett/Win32-Security-0.50/lib/Win32 /Security/Raw.pm "يختلط =" نوفولو noreferrer "> Win32 و:: :: الأمن الخام.

وهناك طرق للقيام بذلك باستخدام حقن عملية، وتأخير مكتبة تحميل الخ.

وأنا لا أراك تفعل ذلك من الأدوات التي قد المدرجة. هذا هو C والبلاد المجمع وبدأت تحصل في الأراضي فيروس الكتابة. بمجرد الحصول على عمل، فإن أي حزم مكافحة الفيروسات نقض تشغيله ومحاولة لعزلها. لذلك كنت ترغب حقا أفضل للقيام بذلك.

و"مع السلطة تأتي من ذلك بكثير ...."

وحظا سعيدا

ومن الممكن لتنفيذ العملية برمتها في واحدة من اللغات المذكورة ولكن لغة مترجمة يكون أفضل لمسح الذاكرة (اعتبارات السرعة وكأن شيئا آخر). هناك دلل (مع المصدر) دعا SigScan المتاحة التي، في حين مصممة لعبة معينة، ربما يمكن تعديلها لتناسب الاحتياجات الخاصة بك مع الحد الأدنى من الجهد.

وبناء على الإجابة الصحيحة براين وهنا مثال سريع وقذرة من استخدام دلل على الحصول على عنوان من داخل الثعبان. هذا هو، بطبيعة الحال، محددة لتنفيذ دلس. "اسم الوحدة النمطية" سيكون عموما اسم DLL كما هو معروض في محركات الغش "تعداد دلس والرموز" الحوار.

ومع المثال براين كدليل و <لأ href = "http://msdn.microsoft.com/en-us/library/ms681674٪28VS.85٪29.aspx" يختلط = "نوفولو noreferrer" عنوان = " MSDN "> 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)

بروك :: ذاكرة و مكتبتها الأساسية <وأ href = "HTTPS : //github.com/a3f/libvas "يختلط =" نوفولو noreferrer "> libvas لهذا الغرض. انها مجرد يدعو {Read,Write}ProcessMemory تحت غطاء محرك السيارة على ويندوز، ولكن كما أنها تدعم منصات أخرى. مثال:

my $mem = Proc::Memory->new(pid => $$); 
$mem->poke(0x12345678, 'L') = 12;
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top