4

起動中のアプリを編集したい(メモリアドレスの編集)、

アドレス00498D45の値を編集したい

現在値 :

MOV BYTE PTR SS:[EBP-423],7

更新された値:

 MOV BYTE PTR SS:[EBP-423],8

私が今まで得たものはこれです(ネットで検索し、これまで私が得たもの):

前もって感謝します!

using System.Runtime.InteropServices;

    [Flags]

        public enum ProcessAccessFlags : uint

{
    All = 0x001F0FFF,
    Terminate = 0x00000001,
    CreateThread = 0x00000002,
    VMOperation = 0x00000008,
    VMRead = 0x00000010,
    VMWrite = 0x00000020,
    DupHandle = 0x00000040,
    SetInformation = 0x00000200,
    QueryInformation = 0x00000400,
    Synchronize = 0x00100000
}

[DllImport("kernel32.dll")]
private static extern IntPtr OpenProcess(ProcessAccessFlags dwDesiredAccess, [MarshalAs(UnmanagedType.Bool)] bool bInheritHandle, int dwProcessId);

[DllImport("kernel32.dll", SetLastError = true)]
private static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, uint nSize, out int lpNumberOfBytesWritten);

[DllImport("kernel32.dll", SetLastError = true)]
static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, [Out] byte[] lpBuffer, int dwSize, out int lpNumberOfBytesRead);

[DllImport("kernel32.dll")]
public static extern Int32 CloseHandle(IntPtr hProcess);

Process process = Process.GetProcessesByName("My Apps Name").FirstOrDefault();

public static bool WriteMemory(Process process, int address, long value, out int bytesWritten)
{
    IntPtr hProc = OpenProcess(ProcessAccessFlags.All, false, process.Id);

    byte[] val = BitConverter.GetBytes(value);

    bool worked = WriteProcessMemory(hProc, new IntPtr(address), val, (UInt32) val.LongLength, out bytesWritten);

    CloseHandle(hProc);

    return worked;
}
4

2 に答える 2

3

あなたの他の質問から:

WriteMemory(Process process,00498D45 , MOV BYTE PTR SS:[EBP-423],8)

これには非常に多くの問題があり、どこから始めればよいかわかりません。まず第一に、これは正しい C# 構文にはほど遠いものです。

  1. 関数を呼び出していますがProcess、署名のようにそこにあります。
  2. 00498D45は、どの基数でも有効な定数ではありません。16 進数を意味する場合 (アドレスを扱っているため、おそらくそうするでしょう)、他のすべての C ライクな言語と同様に、. として表現する必要があります0x00498D45
  3. これは ASCII の x86 アセンブリ コードです (ただし、文字列ではなく、混乱しているだけです)。ASCII アセンブリ コードを別のプロセスのアドレス空間に配置することはできません。

おそらく、プログラムをビルドするときにコンパイルとアセンブリがどのように機能するか、およびプログラムを実行しているときに CPU が実際に何をしているかについて、もう少し調査する必要があります。また、明らかにどこかから取ってきたサンプル コードを読んで理解しようとすることをお勧めします。一緒に石畳になったものを修正するのを手伝ってくれるようにみんなに頼むよりも、何が起こっているのかを学ぶ方がはるかに良いでしょう.</rant>

とにかく、コードをアセンブルすると、次のようになります (再アセンブル):

C68559FEFFFF08    mov byte [ebp-0x1a7],0x8

つまり、命令は実際にはバイト列ですC6 85 59 FE FF FF 08。これが、ターゲット アプリケーションに書き込む必要があるものです。

これは、あなたがやろうとしていることの基礎です:

byte[] new_instr = new byte[] {0xC6, 0x85, 0x59, 0xFE, 0xFF, 0xFF, 0x08};
IntPtr target_addr = (IntPtr)0x00498D45;

int bytesWritten;
WriteProcessMemory(hProcess, target_addr, new_instr, (UInt32)new_instr.Length, out bytesWritten);

WriteMemoryコピー アンド ペーストした記憶機能は、ここで役に立ちません。long問題は、 4 バイトの a のみを書き込むことです。7 バイトを書き込む必要があります。byte[]そのため、パラメーターを使用するようにその関数を変更するか、自分で行う必要があります。


私はあなたの野心に感心しますが、実際にはもう少し低く始めるべきです。C# コードを書いて、C に似た言語でのプログラミングに慣れてください。それから C を書いて、完璧にやらないとクラッシュすることに慣れてください。次に、アセンブリに手を出してみてください - おそらく小さなインライン部分を C コードに書き込んでください。最後に、実行中の他のプロセスの命令をハッキングする準備が整います。

于 2013-05-02T05:30:53.020 に答える
2

MemorySharpのようなインジェクション ライブラリを使用できます(私は作成者です)。これらの関数はすべて、アセンブラ (FASM 構文) を統合する便利な API 内にラップされています。したがって、このコードはあなたが望むものを実行します:

using (var m = new MemorySharp(ApplicationFinder.FromProcessName("My App").First()))
{
    m.Assembly.Inject("MOV BYTE [EBP-423],8", new IntPtr(0x00498D45));
}
于 2013-09-16T01:02:38.883 に答える