2013-08-20 94 views
1

我需要某人編輯標題,我找不到更好的標題。更改另一個應用程序的地址指針


假設有這個簡單的程序稱爲source.exe

#include <stdio.h> 

int main() 
{ 
    int a = 5; 
    printf("%p", &a); 
    return 0; 
} 

我想要寫另一個應用程序,change.exe,改變在上述a

我想是這樣的:

int main() 
{ 
    int * p = (int*) xxx; // xxx is what have printed above 
    *p = 1; 
    printf("%d", *p); 
    return 0; 
} 

它不工作。假設我有管理員權限,是否有辦法做到我上面嘗試過的?謝謝。

+0

由於調試器可以做到這一點,答案是'是的,這是可能的',但它不是你通常期望做的事情。除此之外,'source.exe'會運行得如此簡單,以至於很難正確執行'change.exe'的執行,以便有機會更改'source.exe'中的任何內容。假設你添加了一些機制來延遲'source.exe'的退出,你仍然遇到各種各樣的問題。 O/S的目的之一是阻止ProcessA與ProcessB的內存混淆 - 因此您正在破壞該保護。 –

+1

要知道答案需要操作系統。在Linux上你使用ptrace。在Windows上,您可以使用WriteProcessMemory。 –

+0

一個應用程序中的地址與另一個應用程序中的地址不同。閱讀http://en.wikipedia.org/wiki/Virtual_address_space – chris

回答

0
  1. 爲什麼你認爲這是可能的 - 調試器只能讀取?
  2. 如果有可能,那麼各種各樣的混亂可能發生!
  3. 想起共享內存。
+1

那麼,Windows *上有*'WriteProcessMemory'。 – chris

+1

並看到在Windows中不斷髮生的各種各樣的混亂? – aschepler

+0

我認爲@Ed Heal的意思是「如果它是**那麼簡單」。 –

1

首先,當您運行第二個程序時,第一個程序中的a將會很長時間(或裝入不同的位置)。其次,許多操作系統的保護程序通過將它們加載到不同的空間中。

你真的似乎在尋找的是進程間通信(IPC)機制,特別是共享內存或內存映射文件。

1

在大多數人們處理的傳統計算機上,操作系統使用虛擬內存。這意味着兩個進程都可以使用地址0x12340000,它可以引用兩個不同的內存。

這對於許多原因很有幫助,包括內存碎片,並允許多個應用程序隨機啓動和停止。

在某些系統上,例如TI DSP,沒有MMU,因此沒有虛擬內存。在這些系統上,像你的演示應用程序可以工作。

1

我感覺有點冒險,所以我想在Windows下編寫類似的東西,當然使用WinAPI。像Linux的ptrace一樣,此代碼使用的調用只應由調試器使用,並且通常不會在任何常規應用程序代碼中看到。

此外,打開另一個進程的內存以進行寫入操作需要您使用PROCESS_VM_WRITEPROCESS_VM_OPERATION特權打開進程句柄。但是,只有在打開該進程的應用程序啓用了SeDebugPriviledge權限的情況下才可以執行此操作。我以管理員權限在高級模式下運行應用程序,但我不知道這是否對SeDebugPriviledge有任何影響。

無論如何,這是我用於此的代碼。它是用VS2008編譯的。

#include <windows.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

int main() 
{ 
    char cmd[2048]; 
    int a = 5; 
    printf("%p %d\n", &a, a); 

    sprintf(cmd, "MemChange.exe %lu %x", GetCurrentProcessId(), &a); 
    system(cmd); 

    printf("%p %d\n", &a, a); 

    return 0; 
} 

這是代碼調用MemChange.exe的代碼。

#include <windows.h> 
#include <stdio.h> 

int main(int argc, char **argv) 
{ 
    DWORD pId; 
    LPVOID pAddr; 
    HANDLE pHandle; 
    SIZE_T bytesWritten; 
    int newValue = 666; 

    sscanf(argv[1], "%lu", &pId); 
    sscanf(argv[2], "%x", &pAddr); 

    pHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pId); 
    WriteProcessMemory(pHandle, pAddr, &newValue, sizeof(newValue), &bytesWritten); 
    CloseHandle(pHandle); 

    fprintf(stderr, "Written %u bytes to process %u.\n", bytesWritten, pId); 
    return 0; 
} 

但是請不要使用此代碼。這太可怕了,沒有錯誤檢查,可能像聖地獄一樣泄露。它只是爲了說明WriteProcessMemory可以做什麼而創建的。希望能幫助到你。