Skocz do zawartości
1 maja :: Święto Pracy / 2 maja :: Dzień Flagi / 3 maja :: Święto Konstytucji

ProcMem Help


# CSH External VIP Project

Masz dosyć problemów z czynnikiem zaufania w CS2 lub notorycznymi banami?

Sprawdź CSH External VIP Project.


Więcej informacji  

Rekomendowane odpowiedzi

Okej działa, to został już ostatni błąd który wywala kompilator

 

dds.png

 

@Edit

Usunąłem "-1" z tej linijki i działa, ale to tak troche bezmyślnie, jak mogłbyś mi Hacky wyjaśnić za co odpowiada ta linijka, a w szczególności to -1 to byłbym wdzięczny :) I dzięki za pomoc w rozwiązaniu poprzednich błędów :)


Edytowane przez Wasylo
Odnośnik do komentarza

zamiast zmieniac cos czego nie rozumiesz uzyj castowania const_cast<lpstr>(modul) bo ta uposledzona klasa i tak tego stringa nie modyfikuje, ale w innym przypadku trzeba uwazac

 

co do pytania z -1, zobacz jak wygladaja tablice znakow w c/c++ i zobacz co sie znajduje na koncu nichhttps://en.m.wikipedia.org/wiki/Null-terminated_string 🙂

 

 

 

tu masz aktualne offsety

a client.dll zmien na client_panorama.dll


Edytowane przez krzychu1
Odnośnik do komentarza

@krzychu1 Analizuje sobie kod na auto bh i tam jest taka linijka:

if (GetAsyncKeyState(VK_SPACE) && 0x8000)

I nie wiem za co odpowiada to && 0x8000. Wiem już ze ta funkcja 

(GetAsyncKeyState(VK_SPACE)

Zwraca albo 0 kiedy spacja jest up albo -32768 kiedy spacja jest down. Przez dodanie && 0x8000(32768) funkcja ta zwraca albo 0 albo 1

Wgl jak mam czytać zawartość tego ifa? Jezeli funckja && liczba. Na początku myslalem ze moze sumuje wynik z funkcji i 0x8000 ale to by dalo 0 albo 32768, a zwraca 1 albo 0

Odnośnik do komentarza

@Hacky

"W kodzie binarnym najbardziej znaczący bit świadczy o znaku liczby – gdy jest równy 1, to liczba jest ujemna, gdy 0 – dodatnia. Wyjątkiem jest liczba zero, która w zależności od kodowania może ten bit mieć ustawiony albo wyzerowany."

 

Coś mi tu nie pasuje bo skoro najbardziej znaczący bit wynosi 1 to liczba jest ujemna, w takim razie jak zapisać dodatnią liczbe 255 w 1 bajcie? skoro 11111111 da -255 bo bit o największej wadze to 1

Odnośnik do komentarza
3 godziny temu, Wasylo napisał:

@Hacky

"W kodzie binarnym najbardziej znaczący bit świadczy o znaku liczby – gdy jest równy 1, to liczba jest ujemna, gdy 0 – dodatnia. Wyjątkiem jest liczba zero, która w zależności od kodowania może ten bit mieć ustawiony albo wyzerowany."

 

Coś mi tu nie pasuje bo skoro najbardziej znaczący bit wynosi 1 to liczba jest ujemna, w takim razie jak zapisać dodatnią liczbe 255 w 1 bajcie? skoro 11111111 da -255 bo bit o największej wadze to 1

tak samo, bo dla procesora to nie ma znaczenia, a za wyswietlenie poprawnej liczby w przypadku 11111111 odpowiada kompilator i to czy programista chcial wynik signed lub unsigned 😉

Odnośnik do komentarza

Pomyślałem, że napisze to auto bh bez tej klasy ProcMem. I juz praktycznie wszystko zrobiłem tzn.

1. Pobieram id procesu

2. Wyciągam adres bazowy client.dll

3. Otwieram proces w trybie do odczytu, pobieram dw_LocalPlayer i flagi

4.W pętli otwieram proces w trybie do zapisu

Ta pętla: 

while (1)
	{
		ReadProcessMemory(hProcess, (LPVOID)(dwLocalPlayer + m_fFlags), &flags, sizeof(char), 0);
		if(GetAsyncKeyState(VK_SPACE) & 0x8000)
			if (flags & (1 << 0))
			{
				hProcess = OpenProcess(PROCESS_VM_WRITE | PROCESS_VM_OPERATION, false, pid);
				WriteProcessMemory(hProcess, (LPVOID)(BaseAddress + m_dwForceJump), (LPCVOID)6, sizeof(int), 0);
				cout << GetLastError() << endl; break;
			}
	}

I wszystko działa, przy spacji wchodzi do ifa z flagą tylko nie zapisuje mi funkcja WriteProcessMemory. Po wywołaniu GetLastError dostaje error code = 299, a definicja tego błądu z dokumentacji brzmi :

 

ERROR_PARTIAL_COPY

299 (0x12B)

Only part of a ReadProcessMemory or WriteProcessMemory request was completed.

 

Co może być przyczyną?

Odnośnik do komentarza
		ReadProcessMemory(hProcess, (LPVOID)(dwLocalPlayer + m_fFlags), &flags, sizeof(char), 0);

a potem

				hProcess = OpenProcess(PROCESS_VM_WRITE | PROCESS_VM_OPERATION, false, pid);

?? to dziala w ogole

 


Edytowane przez krzychu1
Odnośnik do komentarza
HANDLE hProcess;
	hProcess = OpenProcess(PROCESS_VM_READ, false, pid);
	DWORD dwLocalPlayer;
	BYTE flags;
	ReadProcessMemory(hProcess, (LPVOID)(BaseAddress + m_dwLocalPlayer), &dwLocalPlayer, sizeof(long), 0);
	while (1)
	{
		ReadProcessMemory(hProcess, (LPVOID)(dwLocalPlayer + m_fFlags), &flags, sizeof(char), 0);
		if(GetAsyncKeyState(VK_SPACE) & 0x8000)
			if (flags & (1 << 0))
			{
				hProcess = OpenProcess(PROCESS_VM_WRITE | PROCESS_VM_OPERATION, false, pid);
				WriteProcessMemory(hProcess, (LPVOID)(BaseAddress + m_dwForceJump), (LPCVOID)6, sizeof(int), 0);
				cout << GetLastError() << endl; break;
			}
	}

@Edit fakt poknociłem xD czytam w petli stan flagi majac uchwyt w trybie do zapisu moj błąd.

 

@Edit 2

Ale to nic nie zmienia bo nawet jak teraz na szybko poprawiłem kod na:

while (1)
	{
		hProcess = OpenProcess(PROCESS_VM_READ, false, pid);
		ReadProcessMemory(hProcess, (LPVOID)(dwLocalPlayer + m_fFlags), &flags, sizeof(char), 0);
		CloseHandle(hProcess);
		if(GetAsyncKeyState(VK_SPACE) & 0x8000)
			if (flags & (1 << 0))
			{
				hProcess = OpenProcess(PROCESS_VM_WRITE | PROCESS_VM_OPERATION, false, pid);
				WriteProcessMemory(hProcess, (LPVOID)(BaseAddress + m_dwForceJump), (LPCVOID)6, sizeof(int), 0);
				CloseHandle(hProcess);
				cout << GetLastError() << endl; break;
			}
	}

To wciąż nie zapisuje i zwraca kod błedu 299


Edytowane przez Wasylo
Odnośnik do komentarza

Czytałem żeby nie używać process_all_access, ale oczywiście tego też próbowałem i jest to samo.

Co do CloseHandle to robiłem już na wszystkie sposoby czyli: 

1. All access

2.  Open w trybie do odczytu -> odczyt -> nadpisanie uchwytu na tryb do zapisu -> zapis

3. Open w trybie do odczytu -> odczyt -> zamknięcie uchwytu -> open w trybie do zapisu -> zapis -> zamknięcie uchwytu

 

Kod co wysłałem to ta trzecia juz próba i zdaje sobie sprawe ze jest napisany z dupy, ale napisałem to tylko w ramach testu bo jakby nie patrzeć to powinno to działać, a to w jaki sposób jest napisany to swoją drogą i w tym momencie nie istotne.

 

Oczywiście ta wersja również zwraca to samo, bo jest to to samo co napisałem wczesniej tylko nie otwieram i zamykam uchwytu milion razy w pętli

	HANDLE hProcess;
	hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, pid);
	DWORD dwLocalPlayer;
	BYTE flags;
	ReadProcessMemory(hProcess, (LPVOID)(BaseAddress + m_dwLocalPlayer), &dwLocalPlayer, sizeof(long), 0);
	while (1)
	{
		ReadProcessMemory(hProcess, (LPVOID)(dwLocalPlayer + m_fFlags), &flags, sizeof(char), 0);
		if(GetAsyncKeyState(VK_SPACE) & 0x8000)
			if (flags & (1 << 0))
			{
				WriteProcessMemory(hProcess, (LPVOID)(BaseAddress + m_dwForceJump), (LPCVOID)6, sizeof(int), 0);
				cout << GetLastError() << endl; break;
			}
	}

A BaseAddress pobieram z tej funkcji:

DWORD_PTR dwGetModuleBaseAddress(DWORD dwProcID, TCHAR *szModuleName)
{
	DWORD_PTR dwModuleBaseAddress = 0;
	HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, dwProcID);
	if (hSnapshot != INVALID_HANDLE_VALUE)
	{
		MODULEENTRY32 ModuleEntry32;
		ModuleEntry32.dwSize = sizeof(MODULEENTRY32);
		if (Module32First(hSnapshot, &ModuleEntry32))
		{
			do
			{
				if (_tcsicmp(ModuleEntry32.szModule, szModuleName) == 0)
				{
					dwModuleBaseAddress = (DWORD_PTR)ModuleEntry32.modBaseAddr;
					break;
				}
			} while (Module32Next(hSnapshot, &ModuleEntry32));
		}
		CloseHandle(hSnapshot);
	}
	return dwModuleBaseAddress;
}

@Edit

Już działa, źle napisałem 1 argument w funkcji WriteprocessMemory a dokładnie (LPCVOID)6

 

Tylko jeszcze jednej rzeczy nie rozumiem w tej pascie co pobrałem.

Kod:

#include "ProcMem.h"
#include <string>
using namespace std;
ProcMem mem;
DWORD Client;

DWORD m_dwLocalPlayer = 0xAB9D9C;
DWORD m_fFlags = 0x100;
DWORD m_dwForceJump = 0x4F2FA78;

int main()
{
	mem.Process("csgo.exe");
	Client = mem.Module("client.dll");
	DWORD dwLocalPlayer = mem.Read<DWORD>(Client + m_dwLocalPlayer);
	while (1)
	{
		BYTE flags = mem.Read<BYTE>(dwLocalPlayer + m_fFlags);

		if (GetAsyncKeyState(VK_SPACE) & 0x8000)
			if (flags & (1 << 0))
				mem.Write(Client + m_dwForceJump, 6);
	}
	
	return 0;
}

A więc w zmiennej Client mam adres bazowy pliku client.dll , w zmiennej m_dwLocalPlayer mam offset. Do zminnej dwLocalPlayer przypisuje wartość obiektu LocalPlayer na podstawie adresu bazowego + offsetu. No bo mem.Read zwraca zawartość komórki pamięci.

A skoro tak, to nie rozumiem linijki 

BYTE flags = mem.Read<BYTE>(dwLocalPlayer + m_fFlags);

funkcja mem.Read przyjmuje przeciez adres komórki którą ma odczytać i zwraca jej zawartość. To dlaczego jako parametr podawana jest wartość jakiejś komórki zamiast jej adres + offset?


Edytowane przez Wasylo
Odnośnik do komentarza
#include <Windows.h>
#include <TlHelp32.h>
#include <iostream> //bardzo potrzebne

HANDLE h{}; //globalna bo TAK
template <typename kek> auto read(std::uintptr_t address) {
    kek buf{};
    ReadProcessMemory(h, (LPCVOID)address, (LPVOID)&buf, sizeof(kek), nullptr);
    return buf;
}

void main()
{
    DWORD id{};
    std::cin >> id; //i tak wpisujesz w swoim to w/e
    h = OpenProcess(PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_VM_OPERATION, 0, id);

    HANDLE			t32{};
    MODULEENTRY32	entry{};
    std::uintptr_t  client{};
    t32 = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, id);
    entry.dwSize = sizeof(entry);

    for (Module32First(t32, &entry); Module32Next(t32, &entry);)
    {
        if (!strcmp(entry.szModule, "client_panorama.dll")) {
            client = (std::uintptr_t)entry.modBaseAddr; break;
        }
    }
    CloseHandle(t32);

    constexpr std::ptrdiff_t flag       = 0x100;
    constexpr std::ptrdiff_t local      = 0xC5C86C;
    constexpr std::ptrdiff_t forcejump  = 0x50DBDFC;

    auto write = [](std::uintptr_t address, const auto& value) { WriteProcessMemory(h, (LPVOID)address, (LPCVOID)&value, sizeof(value), nullptr); }; //turbo lambda ale na rpm nie moge elo c++20 ;(

    auto player = read<std::uintptr_t>(client + local); //raz starczy
    for (;;) {
        if (GetAsyncKeyState(VK_SPACE) & 0x8000)  {
            auto flags 	  = read<int>(player + flag);
            auto ground   = (flags & (1 << 0)); //fl_onground

            write(client + forcejump, (ground) ? 6 : 4);
        }
        Sleep(7); //Lol Na 128 Tick Dziala !!! 
    }
}

masz, kod w 6 minut speedrunowany, tak mi bedzie latwiej wytlumaczyc bo przynajmniej wiem co robi i widze calsoc xD, no all_access nie jest potrzebne ale nie zaszkodzi w szukaniu przyczyny problemu

 

/edit

lol nie widzialem ze sobie poradziles juz, ale jezeli dobrze zrozumialem(a pewnie nie), nie czytasz wartosci client+local, tylko znajdujesz adres do ktorego prowadzi wskaznik localplayera, i potem uzywasz tego adresu by odczytac prawdziwe wartosci, czy to flaga/zdrowie/cokolwiek


Edytowane przez krzychu1
Odnośnik do komentarza

@krzychu1

No okej, mniej więcej rozumiem, ale wytłumacz mi to z tą flagą bo tego nie czaje

 

"W zmiennej Client mam adres bazowy pliku client.dll , w zmiennej m_dwLocalPlayer mam offset. Do zminnej dwLocalPlayer przypisuje wartość obiektu LocalPlayer na podstawie adresu bazowego + offsetu. No bo mem.Read zwraca zawartość komórki pamięci.

A skoro tak, to nie rozumiem linijki 

BYTE flags = mem.Read<BYTE>(dwLocalPlayer + m_fFlags);

funkcja mem.Read przyjmuje przeciez adres komórki którą ma odczytać i zwraca jej zawartość. To dlaczego jako parametr podawana jest wartość jakiejś komórki zamiast jej adres + offset?"


Edytowane przez Wasylo
Odnośnik do komentarza
4 minuty temu, Wasylo napisał:

funkcja mem.Read przyjmuje przeciez adres komórki którą ma odczytać i zwraca jej zawartość. To dlaczego jako parametr podawana jest wartość jakiejś komórki zamiast jej adres + offset?"

Jesli chodzi ci o client + local, to pod tym adresem jest adres localplayer, dlatego to odczytujesz.

Odnośnik do komentarza

nie wiem, od biedy rpm to wrapper do dereferencji pointerow i powinienes o tym poczytac i o rozlozeniu obiektow/wskaznikow w pamieci jezeli chcesz lepiej to ogarnac, bo ja tego nie umiem wytlumaczyc ani sie nie znam na tyle

robiac pierwszy rpm znajdujesz wartosc obiektu z graczem

robiac drugi rpm odczytujesz flagi w obiekcie

Odnośnik do komentarza
Gość
Ten temat został zamknięty. Brak możliwości dodania odpowiedzi.

  Tagi

×
×
  • Dodaj nową pozycję...

Powiadomienie o plikach cookie

Umieściliśmy na Twoim urządzeniu pliki cookie, aby pomóc Ci usprawnić przeglądanie strony. Możesz dostosować ustawienia plików cookie, w przeciwnym wypadku zakładamy, że wyrażasz na to zgodę. Regulamin. Polityka prywatności