2017-01-08 2 views
0

Ich fürchte, die Frage ist wirklich, wirklich einfach, aber selbst ich fange an, die Idee von Zeigern zu greifen, Hinweise von erfahrenen Benutzern verkürzen die Zeit, die ich dafür ausgeben muss alles verstehen. Ich habe ein einfaches Beispiel, ich werde nicht näher darauf eingehen, was es später tun sollte, weil ich glaube, dass mein Fehler etwas sehr Grundlegendes ist. Ich bekomme:Zugriffsverletzung beim Berechnen eines Zeigers

Ausnahme ausgelöst: Lesezugriffsverletzung. _First war 0x815110.

Wenn Sie diesen Code ausführen:

#include <Windows.h> 
#include <iostream> 
#include "Header.h" 

#pragma comment(linker, "/SECTION:.data,RWE") 

using std::cout; 
using std::endl; 

int main() { 

    DWORD dwProcessID = 0; 

    cout << "Looking for game process..." << endl; 

    while (dwProcessID == 0) { 
     dwProcessID = GetProcessID(L"PathOfExile.exe"); 
     Sleep(100); 
    } 

    std::cout << "Game Client found" << std::endl; 

    printf("dwProcessID = %p\n", dwProcessID); 

    HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwProcessID); 
    MODULEENTRY32 module; 
    module.dwSize = sizeof(MODULEENTRY32); 
    Module32First(snapshot, &module); 

    HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, dwProcessID); 

    HANDLE hToken = NULL; 
    if (!OpenProcessToken(hProcess, TOKEN_ADJUST_PRIVILEGES, &hToken)) 
     printf("Failed to open access token\n"); 

    if (!SetPrivilege(hToken, SE_DEBUG_NAME, TRUE)) 
     printf("Failed to set debug privilege\n"); 


    printf("PoE base address = %p\n", module.modBaseAddr); 

    BYTE jmp[] = "\xBA\x00\x00\x80\x3F\x89\x10\x89\x16\xE9\x00\x00\x00\x00"; 

    BYTE *dwMaphack = (BYTE*)(module.modBaseAddr + 0x4D5110); 
    cout << dwMaphack << endl; 

    *(DWORD*)&jmp[10] = (DWORD)(dwMaphack - jmp) - 6; 

    DWORD dwOldProt; 

    VirtualProtectEx(hProcess, (LPVOID)dwMaphack, 8, PAGE_EXECUTE_READWRITE, &dwOldProt); 

    // tbc 

    while (1) { 
    } 

    return 0; 
} 

Die offenen Prozess Methoden und andere grundlegende Dinge sind im Kopf und sie funktionieren, was ich nicht bekommen ist, warum, wenn ich den Byte-Zeiger BYTE ändern * dwMaphack zu DWORD * dwMaphack, gibt es keinen Zugriffsverletzungsfehler mehr?

Ich versuche, meinen Code auf einem veralteten Code von Someones basiert, der nicht mehr funktioniert, so dass der Grund für diese Operationen nur teilweise für mich bekannt ist, weiß ich, was es in Programmierungsbegriffen tun soll, aber ich kenne den Effekt im Spiel noch nicht. Ich denke nicht, dass es in Bezug auf den Fehler, den ich bekomme, wichtig ist. Vielen Dank im Voraus für die Antworten!

+0

@RbMm, eine weitere Herausforderung? :-D – MTM

+0

Zeigerarithmetik basiert auf der Größe des Ziels. – stark

+0

Ein Fehler bei der Berechnung des Zeigertyps tritt bei einem Zugriffsverletzungsfehler auf? – MTM

Antwort

0

Hier ist Ihr Problem:

cout << dwMaphack << endl; 

Dieser versucht, den Wert, den dwMaphack Punkte, nicht der Wert des Zeigers zu drucken. Da der Zeiger nur im Remote-Prozess gültig ist, führt der Versuch der Dereferenzierung zu einer Zugriffsverletzung.

Dies funktioniert:

cout << (DWORD_PTR)dwMaphack << endl; 
+0

Danke, es tut! – MTM

3

BYTE ein Alias ​​für unsigned char ist.

std::cout hat eine überladene operator<<, die einen unsigned char* Zeiger als Eingabe akzeptiert und druckt es als Zeichenkette (wie von Harry Johnston erklärte, https://stackoverflow.com/a/41538200/7376565). Es stürzt also ab, wenn es versucht, auf Speicher zuzugreifen, auf den es keinen Zugriff hat.

std::cout keine operator<< Überlastung für DWORD* haben (aka unsigned long*), aber es hat eine für void* haben, so dass jeder Nicht-Zeichenzeiger wird nur den Wert des Zeigers selbst drucken. Wenn Sie dwMaphack zu DWORD* ändern, versucht operator<< nicht, auf den Speicher zuzugreifen, der dwMaphack verweist, so dass keine Zugriffsverletzung auftritt.

+0

Danke Jungs, das hilft, Sachen in meinem Kopf zu sortieren! – MTM

+0

Ich empfehle nicht zu 'DWORD *' überhaupt zu ändern.Gerade beschrieben der Grund, warum der Code nicht abstürzt, wenn Sie 'DWORD *' verwenden. Ich ziehe es vor, Zeiger auf Typ wie "DWORD_PTR", "ULONG_PTR" (zeigergroße ganze Zahl) zu konvertieren, wenn ich einen Zeigerwert benötige. –

+0

Ah, ich hatte diesen Teil der Frage übersehen. Mein Fehler. –

Verwandte Themen