1. 程式人生 > >C++&C#外掛(內存修改)

C++&C#外掛(內存修改)

net環境 dword cli amp blank 欺騙 ech word 無線

大學時候因為主修C#語言(當然現在做的是javaweb開發),那時在網上學了用C#做外掛的教程,外掛嘛,大家都懂的.這裏只是低級的修改內存,不涉及到截獲數據包.如果是欺騙服務器,修改服務器數據,那就難的多了.這裏給出兩個修改內存代碼的例子,一個是C#的一個是C++的.C#做東西比較簡單,但是運行需要.net環境.C++編譯出來的exe執行文件就沒有這多要求.查找基質和偏移量的方法大都是用CE,網上教程很多.這裏只有簡單的代碼給大家參考

首先看看C#的,我封裝了一個ECHelper.cs工具類,代碼如下

        //打開進程獲取句柄
        [DllImport("kernel32.dll
", EntryPoint = "OpenProcess")] public static extern IntPtr OpenProcess(int desiredAccess, bool heritHandle, int pocessID);//訪問權限(16進制),是否繼承句柄,進程ID //關閉句柄 [DllImport("kernel32.dll", EntryPoint = "CloseHandle")] public static extern void CloseHandle(IntPtr hObject);
//讀取內存 [DllImport("kernel32.dll", EntryPoint = "ReadProcessMemory")] public static extern bool ReadProcessMemory(IntPtr hProcess, IntPtr baseadress, IntPtr buffer, int nsize, IntPtr bytesread); //寫入內存 [DllImport("kernel32.dll", EntryPoint = "WriteProcessMemory")]
public static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr baseadress, long[] buffer, int nSize, IntPtr byteswrite); //根據進程名獲得PID public static int GetPIDByProcessName(string name) { Process[] pros = Process.GetProcessesByName(name); if (pros.Count() > 0) { return pros[0].Id; } else { return 0; } } public static int ReadMemoryValue(string name, IntPtr baseadress) { try { byte[] buffer = new byte[4]; IntPtr bufferadress = Marshal.UnsafeAddrOfPinnedArrayElement(buffer, 0); IntPtr hprocess = OpenProcess(0x1F0FFF, false, ECHelper.GetPIDByProcessName(name)); ReadProcessMemory(hprocess, baseadress, bufferadress, 4, IntPtr.Zero); CloseHandle(hprocess); return Marshal.ReadInt32(bufferadress); } catch { return 0; } } public static void WriteMemoryValue(string name, IntPtr baseadress, long value) { IntPtr hprocess = OpenProcess(0x1F0FFF, false, ECHelper.GetPIDByProcessName(name)); WriteProcessMemory(hprocess, baseadress, new long [] { value }, 4, IntPtr.Zero); CloseHandle(hprocess); }

調用方法如下

string name = "cstrike";
int baseadress = 0x025069BC;
private void btnShoot_Click(object sender, EventArgs e)
{
      timShoot.Start();
}

private void timShoot_Tick(object sender, EventArgs e)
{
      timShoot.Interval = 300;
      int adress1 = ECHelper.ReadMemoryValue(name, (IntPtr)baseadress);
      adress1 = adress1 + 0x7C;
      int adress2 = ECHelper.ReadMemoryValue(name, (IntPtr)adress1);
      adress2 = adress2 + 0x5EC;
      int adress3 = ECHelper.ReadMemoryValue(name, (IntPtr)adress2);
      adress3 = adress3 + 0xCC;
      ECHelper.WriteMemoryValue(name, (IntPtr)adress3, 0x64);          //cs子彈無線
}

這裏是C#源碼

下面看C++語言的

    DWORD  getLastError;  
    //1.根據窗口名獲取窗口  
    HWND hWinmine = FindWindow(NULL,"Counter-Strike");
    DWORD dwPID = 0;  //窗口進程標示
    //2.根據窗口獲取pid 
    GetWindowThreadProcessId(hWinmine, &dwPID);  
    if (dwPID == 0)  
    {  
        printf("獲取PID失敗\n");  
        return -1;  
    }  
    //3.根據pid獲取進程
    HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, dwPID);  
    if (hProcess == NULL) 
    {  
        printf("進程打開失敗\n");  
        getLastError = GetLastError();  
        return -1;  
    }  
  
    DWORD dwNum = 0, dwSize = 0;  
      
    //基址  
    DWORD CSBaseAddress = 0x025069BC;  
    //基址值  
    DWORD CSBaseAddressValue = 0;  
    if (0 == ReadProcessMemory(hProcess, (LPVOID)CSBaseAddress, &CSBaseAddressValue, sizeof(DWORD), &dwSize))  
    {  
        printf("靜態址獲取失敗\n");  
        getLastError = GetLastError();  
        return -1;  
    }  

    //一級偏移  
    DWORD CSOffsetFirst = 0x7C;  
    //一級偏移值  
    DWORD CSOffsetFirstValue = 0;  
    if (0 == ReadProcessMemory(hProcess, (LPVOID)(CSBaseAddressValue + CSOffsetFirst), &CSOffsetFirstValue, sizeof(DWORD), &dwSize))  
    {  
        printf("一級偏移獲取失敗\n");  
        getLastError = GetLastError();  
        return -1;  
    }  
  
    //二級偏移  
    DWORD CSOffsetSecond =  0x5EC;  
    //二級偏移值  
    DWORD CSOffsetSecondValue = 0;  
    if (0 == ReadProcessMemory(hProcess, (LPVOID)(CSOffsetFirstValue + CSOffsetSecond), &CSOffsetSecondValue, sizeof(DWORD), &dwSize))  
    {  
        printf("二級偏移獲取失敗\n");  
        getLastError = GetLastError();  
        return -1;  
    }

    //三級偏移  
    DWORD CSOffsetThird = 0xCC;  
    DWORD CSNum=0;  //這裏是當前子彈值
    if (0 == ReadProcessMemory(hProcess, (LPVOID)(CSOffsetSecondValue + CSOffsetThird), &CSNum, sizeof(DWORD), &dwSize))  
    {  
        printf("三級偏移獲取失敗\n");  
        getLastError = GetLastError();  
        return -1;  
    }

    int modifyCS;  
    printf("CSNum:%d\n", CSNum);  
    printf("輸入你要修改後的值:");  
    scanf("%d", &modifyCS);  
    //更改值
    WriteProcessMemory(hProcess, (LPVOID)(CSOffsetSecondValue + CSOffsetThird), &modifyCS, sizeof(DWORD), &dwSize);  
      
    CloseHandle(hProcess);  //關閉進程
    system("pause");  //窗口停留

C++源碼

C++&C#外掛(內存修改)