天天看點

通過ReadProcessMemory讀取程序記憶體通過WriteProcessMemory改寫程序的記憶體

修改一個程式的過程如下:1、獲得程序的句柄 2、以一定的權限打開程序 3、調用ReadProcessMemory讀取記憶體,WriteProcessMemory修改記憶體,這也是記憶體更新檔的實作過程。下面貼出的是調用ReadProcessMemory的例程

#include <windows.h>
#include <tlhelp32.h>
BOOL CALLBACK EnumChildWindowProc(HWND hWnd,LPARAM lParam);//枚舉記事本中的子視窗
char mess[999999];
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd)
{
    HWND nphWnd=::FindWindow("notepad",NULL);
    if(nphWnd)
    {
        char temp[1024];
        PROCESSENTRY32 pe32;
        pe32.dwSize=sizeof(pe32);
        HANDLE hProcessSnap=::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);//獲得程序清單的快照,第一個參數可以有其他選項,詳細請參考MSDN
        if(hProcessSnap==INVALID_HANDLE_VALUE)
        {
            ::MessageBox(NULL,"CreateToolhelp32Snapshot error","error",MB_OK);
            return 0;
        }
        HANDLE hProcess;
        BOOL bMore=::Process32First(hProcessSnap,&pe32);//獲得第一個程序的資訊
        while(bMore)
        {
            ::wsprintf(temp,"%s",pe32.szExeFile);
            if(!::strcmp(temp,"Maxthon.exe"))
            {
                hProcess=::OpenProcess(PROCESS_ALL_ACCESS,false,(DWORD)pe32.th32ProcessID);
                if(hProcess==NULL)
                {
                    ::wsprintf(temp,"%s","打開程序失敗!");
                    ::strcat(mess,temp);
                }
                else
                {
                    ::wsprintf(temp,"%s","打開程序成功!");
                    ::strcat(mess,temp);
                    //讀取記憶體中内容
                    int tmp;
                    DWORD dwNumberOfBytesRead;
                    if(!::ReadProcessMemory(hProcess,(LPCVOID)0x00400000,&tmp,4,&dwNumberOfBytesRead))
                    {
                        ::wsprintf(temp,"%s","讀取失敗");
                        ::strcat(mess,temp);
                    }
                    else
                    {
                        ::wsprintf(temp,"%x",tmp);
                        ::strcat(mess,temp);
                    }
                }
                break;
            }
            bMore=::Process32Next(hProcessSnap,&pe32);//獲得其他程序資訊
        }
        ::EnumChildWindows(nphWnd,EnumChildWindowProc,0);//獲得記事本的edit視窗,列印程序資訊
        return 0;
    }
    else
    {
        ::MessageBox(NULL,"please open notepad","error",MB_OK);
        return 0;
    }
}
BOOL CALLBACK EnumChildWindowProc(HWND hWnd,LPARAM lParam)
{
    char temp1[256];
    if(hWnd)
    {
        ::GetClassName(hWnd,temp1,255);
        if(!::strcmp(temp1,"Edit"))//得到edit子視窗句柄
        {
            ::SendMessage(hWnd,WM_SETTEXT,0,(LPARAM)mess);
            return 0;
        }
    }
    return true;
}
           

程式讀取400000位址4個位元組的資料,對于exe檔案,也就是PE檔案,讀出來的内容永遠都是905a4d,翻譯成ASCII字元也就是“MZ”,下面要進行的就是調用WriteProcessMemory修改記憶體的内容了,具體程式放在下篇文章中

通過WriteProcessMemory改寫程序的記憶體

以PROCESS_ALL_ACCESS權限打開程序以後既可以使用ReadProcessMemory讀取程式記憶體,也可以使用WriteProcessMemory改寫程式的記憶體,這也是一些記憶體更新檔使用的招數,以下是程式的實作代碼

#include <windows.h>
#include <tlhelp32.h>
BOOL CALLBACK EnumChildWindowProc(HWND hWnd,LPARAM lParam);//枚舉記事本中的子視窗
char mess[999999];
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd)
{
    HWND nphWnd=::FindWindow("notepad",NULL);
    if(nphWnd)
    {
        char temp[1024];
        PROCESSENTRY32 pe32;
        pe32.dwSize=sizeof(pe32);
        HANDLE hProcessSnap=::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);//獲得程序清單的快照,第一個參數可以有其他選項,詳細請參考MSDN
        if(hProcessSnap==INVALID_HANDLE_VALUE)
        {
            ::MessageBox(NULL,"CreateToolhelp32Snapshot error","error",MB_OK);
            return 0;
        }
        HANDLE hProcess;
        BOOL bMore=::Process32First(hProcessSnap,&pe32);//獲得第一個程序的資訊
        while(bMore)
        {
            ::wsprintf(temp,"%s",pe32.szExeFile);
            if(!::strcmp(temp,"button.exe"))
            {
                hProcess=::OpenProcess(PROCESS_ALL_ACCESS,false,(DWORD)pe32.th32ProcessID);
                if(hProcess==NULL)
                {
                    ::wsprintf(temp,"%s","打開程序失敗!");
                    ::strcat(mess,temp);
                }
                else
                {
                    ::wsprintf(temp,"%s","打開程序成功!");
                    ::strcat(mess,temp);
                    //改寫記憶體中内容
                    int tmp=97;//ascii:a
                    DWORD dwNumberOfBytesRead;
                    if(!::WriteProcessMemory(hProcess,(LPVOID)0x0040505d,&tmp,1,&dwNumberOfBytesRead))
                    {
                        ::wsprintf(temp,"%s","寫入失敗");
                        ::strcat(mess,temp);
                    }
                    else
                    {
                        ::wsprintf(temp,"%s","寫入成功");
                        ::strcat(mess,temp);
                    }
                }
                break;
            }
            bMore=::Process32Next(hProcessSnap,&pe32);//獲得其他程序資訊
        }
        ::EnumChildWindows(nphWnd,EnumChildWindowProc,0);//獲得記事本的edit視窗,列印程序資訊
        return 0;
    }
    else
    {
        ::MessageBox(NULL,"please open notepad","error",MB_OK);
        return 0;
    }
}
BOOL CALLBACK EnumChildWindowProc(HWND hWnd,LPARAM lParam)
{
    char temp1[256];
    if(hWnd)
    {
        ::GetClassName(hWnd,temp1,255);
        if(!::strcmp(temp1,"Edit"))//得到edit子視窗句柄
        {
            ::SendMessage(hWnd,WM_SETTEXT,0,(LPARAM)mess);
            return 0;
        }
    }
    return true;
}