ANASAYFA

AİMBOT Yapma

  • Haritanın her yerinde yumurtlayan canavarları öldür. (%)
  • Öğeleri toplamak.
  • Her düzeyin sırrını kilidini açın.

Shareware indirmek için kullanılabilir ModDB 9.
image 

Ben bir süre oyun oynayarak başladı, bu uygulanan
hareket sistemi hatırlattı.
Sol/sağ ok tuşları ekran döndürme sağlar.
Yukarı/aşağı tuşları ileri ve geri hamle leri mümkün kılarken.
DView 

Görüntü’nün giriş noktası aramak için, Ben WinDBG kullanılan ve Doom95.exe sürecine bağlı.
image 

Fark etmiş olabileceğiniz gibi, 64 bitlikbir makineyle çalışıyorum.


Ama yürütülebilir

image 32-bit:

‘lfanew PE imza ofset tutar.




yanındaki alana “Makine”denir, türünü gösteren bir USHORT . image bu yüzden wow64exts kullanarak

geçmek için devam etti. –

image
image

Daha sonra yüklü modülleriçinde “Doom” baktı ve belirtilen modülün giriş noktası ayıklamak için $iment kullanılır.

0:011:x86> lm m Doom*
start             end                 module name
00400000 00690000   Doom95   C (no symbols)           
10000000 10020000   Doomlnch C (export symbols)       Doomlnch.dll
0:011:x86> ? $iment(00400000)
Evaluate expression: 4474072 = 004444d8

IDA bu adrese atlama ilgi işlevini ortaya koymaktadır: _WinMain.
Faydalı bilgiler içeren parçalar için arama image
başlatıldı.

push    eax               ; nHeight
add     edx, ebx
push    edx               ; nWidth
push    0                 ; Y
push    0                 ; X
push    0x80CA0000        ; dwStyle
push    offset WindowName ; "Doom 95"
push    offset ClassName  ; "Doom95Class"
push    0x40000           ; dwExStyle
call    cs:CreateWindowExA

Arama tarafından kullanılan statik WindowName Doom’s PIDbizim hızlı alma neden olacaktır.
FindWindow() ve GetWindowThreadProcessId() kombinasyonu bunu mümkün kılar.
image

	HWND	DoomWindow;
	DWORD	PID;
	DoomWindow = FindWindow(NULL, _T("Doom 95"));

	if (! DoomWindow)
	{
		goto out;
	}

	GetWindowThreadProcessId(DoomWindow, &PID);
	printf("PID: %d\n", PID);

	out:
	return 0;

image
_WinMain prosedüründe dikkatimi çeken bir sonraki şey aşağıdaki satırlar vardı.

loc_43AF74:
mov     edi, 1
mov     eax, ds:dword_60B00C
xor     ebp, ebp
mov     ds:dword_60B450, edi
mov     ds:dword_4775CC, ebp
cmp     eax, edi
jz      short loc_43AFB8
call    cs:GetCurrentThreadId
push    eax             ; dwThreadId
mov     edx, ds:hInstance
push    edx             ; hmod
push    offset fn       ; lpfn
push    2               ; idHook
call    cs:SetWindowsHookExA
mov     ds:hhk, eax

İşlev SetWindowsHookEx Sistem Olaylarını izlemekiçin geçerli iş parçacığı içinde bir kanca(fn) yükler. Bu örnekte özellikle 2’ye eşit bir idHook kullanır ve MSDN’ye göre WH_KEYBOARD.
Geri arama işlevi image
belgelenmiş KlavyeProc 1 Prototip. Bu wParam Sanal Anahtar kodu yakalar.
Bunun üzerine, fn işlevi belirli bir tuşa da basıldığında kontrol etmek

image
için GetAsyncKeyState çağırır: ok tuşları işleyen işlev sub_442A90.
– image

loc_439229:
mov     ebx, [esp+2Ch+v14]
mov     edx, [esp+2Ch+lParam]
mov     eax, esi
call    sub_442A90

Oyuncu bilgileri

Hafızada saklanan yapıyı bilmememiz bizi dezavantajlı duruma sokuyor.
Sağlık ağırlıklı olarak depolanırnerede bulmak için, ben bir DWORD(4 bayt) olduğu varsayımı ile Cheat Engine kullanarak olacak: “\x64\x00\x00\x00\x00”image Daha sonra karakter hasarlı almak için devam edeceğiz , ve ‘Sonraki Scan’ yeni değer için .


Biz 5 farklı işaretçilerile sona erer.
Sonuncusu siyah renk, dinamik bir adres olduğu anlamına gelir , herhangi bir gözlemlenebilir değişiklik neden olmaz değiştirerek . image

Diğerleri açıkça statik, bunların 3 /4 değiştirerek orijinal değeri geriyol açar , hangi 1 / 4 sol ebeveynolduğu anlamına geliyordu , ve geri kalanı sadece değerini kopyalamak.
00482538: Ekranda görünen sağlık.
03682944Veliile güncellenmediğiiçin umut verici bir adres .
Sağlık iki farklı yerlerdesaklanır, hangi bir şey ama bir yemanlamına gelir. İlkinin değerini 1’eayarladım ve sonra bir canavar tarafından saldırıya uğradım.


image Sonuç:
Ekranda görünen değer 0’da asılı kalır ve karakter ölmez.

image

İkinci her saldırı da azalandevam ederken , etkili gerçek değeridüzenlenen anlamına gelir.
Değeri seçip CTRL+B’yitıklatarak bellek bölgesini incelememiz gerekir.
Ekran Türünü Bayt hex’ten 4 Bayt hex’e çevirebiliriz. image


– Bu çalışmak daha kolaydır, ben sınırlı bir aralıkta en yakın işaretçi aramaya başladı , ve 3682A24 olduğu ortaya çıktı .


image image

image



image
Daha sonra içeriğini görmek için adrese gideriz: Nesnenin durumunun boş olduğunu ve yapının başında Geriye ve İleri bağlantısını tuttuğunu fark edin. image

Bir kıvılcım

Bana çok zaman kazandıran fikir!
HILE KODLARı 19, Ben hem mutlu ve şok gerçekten var olduğunu öğrenmek için!

DOOMWiki, her iletinin algılanmasında görünen iletileri içerir.
İki komut, manipüle ettikleri bilgiler yüzünden olağanüstüydü.Görüntü1017×39 4.9 KB

Görüntü771×52 24.7 KB

Sihirli anahtar kelimeler: “ang=” ve “BY REQUEST…”.
İlkinin kullanımı aşağıdaki durumlarda gerçekleşir:

loc_432776:
mov     eax, offset off_4669BC
movsx   edx, byte ptr [ebp+4]
call    sub_414E50
test    eax, eax
jz      short loc_4327D4
mov     edx, ds:dword_482A7C
lea     eax, ds:0[edx*8]
add     eax, edx
lea     eax, ds:0[eax*4]
sub     eax, edx
mov     eax, ds:dword_482518[eax*8]
mov     ebx, [eax+10h]
push    ebx
mov     ecx, [eax+0Ch]
push    ecx
mov     esi, [eax+20h]
push    esi
push    offset aAng0xXXY0xX0xX ; "ang=0x%x;x,y=(0x%x,0x%x)"
push    offset unk_5F2758
call    sprintf_

Bu önemli ve ce tabloyaeklenmesi için değerlidir.








Bir yapı düzeni de sonuçlandırılır: @) +0x10: y @) + 0xC: x @) +0x20: açı ben hemen eksik Z koordinatı fark ettim . image



Ben birkaç testten sonra +0x14 olduğunu fark sona erdi. (Yukarı ve aşağı gidiyoruz.)


Ben düşman farklı bir irtifada olsa bile: atış hala vurur ve bu yüzden diğer taraftan Z. X, Y ve Açı göz ardı mesafe hesaplama ve açı ölçümü nedeniyle önemli olduğunu biliyordum.
DCoords


Tuttukları değerler garip görünüyor, yüzerler mi?
image Hayır,
öyle görünmüyor.
image Şimdilik bildiğim tek şey, görünümün modifikasyon üzerine değiştiğidir.

İkinciye geçerek:

loc_432533:
mov     eax, offset off_466898
movsx   edx, byte ptr [ebp+4]
call    sub_414E50
test    eax, eax
jz      short loc_43255E
mov     eax, ds:dword_5F274C
mov     dword ptr [eax+0D8h], offset aByRequest___ ; "By request..."
call    sub_420C50
jmp     loc_4326BA

İdamın sadece sub_420C50 geçtiğini görebiliriz.

sub_420C50 proc near
push    ebx
push    ecx
push    edx
push    esi
mov     esi, ds:dword_484CFC
cmp     esi, offset dword_484CF8
jz      short loc_420C92
loc_420C62:
cmp     dword ptr [esi+8], offset sub_4250D0
jnz     short loc_420C87
test    byte ptr [esi+6Ah], 40h
jz      short loc_420C87
cmp     dword ptr [esi+6Ch], 0
jle     short loc_420C87
mov     ecx, 2710h
mov     eax, esi
xor     ebx, ebx
xor     edx, edx
call    sub_422370
loc_420C87:
mov     esi, [esi+4]
cmp     esi, offset dword_484CF8
jnz     short loc_420C62
loc_420C92:
pop     esi
pop     edx
pop     ecx
pop     ebx
retn
sub_420C50 endp

[484CFC] ile başlayıp İleri bağlantısı(+4) 484CF8’e eşitse sona eren Nesnelerin bir listesinigeçiş ettiğini görebiliriz.
Player Object’in listeye eklenmesi, kullanılabilir tüm varlıkları içerdiğini gösterir. image

Üç kontrol var:

[Varlık + 0x08] ==

0x4250D0 [Varlık + 0x6A] & 0x40

[Varlık + 0x6C] > 0


Ben bu Ofsetlerdetutulan

image
Oyuncu Nesnesi ne merak ediyordum : @) + 0x8: Fonksiyon işaretçisi(Pass).
@ ) +0x6A: Byte (Hata)IsMonster kontrol gibi görünüyor.
@) +0x6C: Sağlık(Pass).

Küçük bir hata

“Bunu daha önce yapan oldu mu?” diye merak ettim.
Ben de araştırdım:

metin:”ang=0x%x;x,y=(0x%x,0x%x)” doom

Ve kaynak kodun mevcut olduğunu öğrendim.  
image
Ama, hey! Ben zaten daha fazla bilgi gerekli, ve bu kolay bir yol gösterme oldu .


image –

Yani

 image 

aradığımız yapı


image

d_player.h 4ilginç öğenin adı mo.

//
// Extended player object info: player_t
//
typedef struct player_s
{
    mobj_t*		mo;
...

Doğası mobj_t, ilan p_mobj.h 1.

// Map Object definition.
typedef struct mobj_s
{
    // List: thinker links.
    thinker_t		thinker;

    // Info for drawing: position.
    fixed_t		x;
    fixed_t		y;
    fixed_t		z;

    // More list: links in sector (if needed)
    struct mobj_s*	snext;
    struct mobj_s*	sprev;

    //More drawing info: to determine current sprite.
    angle_t		angle;	// orientation
...

Boyutu thinker_t 1 is: boyutof(PVOID) * 3 = 4 * 3 = 12.
Sonra X, Y ve Z (0x0C, 0x10, 0x14)gelir.
İki işaretçi @0x18 göz ardı edilir(4 * 2 = 8).
Açı 0x20’de.

...
    int			health;

    // Movement direction, movement generation (zig-zagging).
    int			movedir;	// 0-7
    int			movecount;	// when 0, select a new dir

    // Thing being chased/attacked (or NULL),
    // also the originator for missiles.
    struct mobj_s*	target;
...

Hedef öğe ilginç, sözde saldırıya uğrayan Harita Nesnesi için bir işaretçi tutar!
Onun ofset hesaplamak zor değil,çünkü Sağlık 0x6C olduğunu biliyorum.
FIELD_OFFSET(mobj_t, hedef) = 0x6C + sizeof(int) * 3 = 0x78.
r_local.h’deki aşağıdaki satır, Anglesiçin bir arama tablosu/işlevi olduğunu ve neden garip değerlerolduğunu açıklar.

// Binary Angles, sine/cosine/atan lookups.
#include "tables.h"

Hedef elementin bizim için ne getireceğini görme nin zamanı! Ben sadece oyun başladı bu yana, değeri NULL olduğunu .

image
Saldırmak veya bir canavar tarafından saldırıya uğramak bir değer değişimineyol açar.
image Ama canavar

.
image

Sağlık ölüm tek göstergesidir eğer <= 0 . image Ve bu tek sorun değil:

İkinci bir Canavar saldıran herhangi bir değişiklik meydana neden olmaz.
Ben düzenli olarak güncellenmesini istiyorum bu yana, ben

zorunda kaldı. Doom95.exe’yiyeniden başlattım,

seçtim ve:
image
– –

image


image
Şimdi bir düşmanla savaşmaya başlayabiliriz:

image


olan talimattır.

 image

biraz geri gidiyor, bazı basit kontroller vardır:

Hedef NULL mu? Oyuncunun kendisine eşit mi?

image 

EBX kaydının kaynağı seçilen talimattır ve konumu : 00422684.
Tüm yapmam gereken bir JMP 422684yerleştirmek için bir yer bulmaktı.
Ben 0042264F seçimi sona


image
erdi

image
: – –

biz imagedeğildir .
Şimdi her saldırıda değişip değişmeyelimbakalım :Canavar




image

Bulmacanın son parçası

Canavarlar doğru benim karakter hedefolabilir .
Açı ölçümüiçin sorumlu bir fonksiyonun var olduğunu biliyordum, sadece onu bulmam gerekiyordu.
Birkaç saat sonra arama,ben bakarak sona erdi p_enemy.c 1;

boolean P_CheckMeleeRange (mobj_t*	actor)
{
    mobj_t*	pl;
    fixed_t	dist;
	
    if (!actor->target)
	return false;
		
    pl = actor->target;
    dist = P_AproxDistance (pl->x-actor->x, pl->y-actor->y);

    if (dist >= MELEERANGE-20*FRACUNIT+pl->info->radius)
	return false;
	
    if (! P_CheckSight (actor, actor->target) )
	return false;
							
    return true;		
}

İlginç fonksiyonlar koleksiyonu!
P_AproxDistance()

P_CheckSight()

Ve en

image
umut verici olanı: R_PointToAngle2()ve tanımı aşağıdakigibidir:

angle_t
R_PointToAngle2
( fixed_t	x1,
  fixed_t	y1,
  fixed_t	x2,
  fixed_t	y2 )
{	
    viewx = x1;
    viewy = y1;
    
    return R_PointToAngle (x2, y2);
}

Ben Oyuncunun X biliyordu, Y hemen önce çağrıldı. Ben aramaları izlemek için bu bilgileri kullanılan ve

image


image 

erişimler için izledim:– Bir kez bir , biz sonuç

:
Görüntü407×552 12.2 KB
Ben ortada en az isabet sayısıolanlar ile başladı . İkincisi aradığımız şeye benziyor!
image

EAX ve ECX onun (X, Y) koordinatları depolayarak EAX Hedef yükleyerek 0042DB10 aramak için hazırlar , EAX ve EDX canavar ın bu tutun . image

Bunun bir __fastcall olduğu var.
Fonksiyon sökse gösterir:

image Tanıdık

Bunu

//
// A_FaceTarget
//
void A_FaceTarget (mobj_t* actor)
{	
    if (!actor->target)
	return;
    
    actor->flags &= ~MF_AMBUSH;
	
    actor->angle = R_PointToAngle2 (actor->x,
				    actor->y,
				    actor->target->x,
				    actor->target->y);
    
    if (actor->target->flags & MF_SHADOW)
	actor->angle += (P_Random()-P_Random())<<21;
}

Ben sadece IDAkullanacağız .



– Gibi görünüyor, hedef NULL ise dönerek başlar , sonra ve s [ Monster +0x68 ] 0xDF ile . image image



image Ne üzücü, ben CE başından beri bakıyordu, welp :joy:.
A_FaceTarget 0041F670olduğunu.

Yapım

Oyun hakkında öğrendiğimiz her şey c++ile bir şeyler sarmaya başlamamızı sağlayacaktır.
ADoom.holuşturalım:

#ifndef __ADOOM_H__
#define __ADOOM_H__

class ADoom {
public:
	ADoom(DWORD);
	~ADoom();
private:
	HANDLE	DH;
};

#endif

Ve ADoom.c:

#include <cstdio>
#include <cstdlib>
#include <stdexcept>
#include <tchar.h>
#include <Windows.h>

#include "ADoom.h"

ADoom::ADoom(DWORD CPID)
{
	DH = OpenProcess(PROCESS_ALL_ACCESS, FALSE, CPID);

	if (DH != INVALID_HANDLE_VALUE)
	{
		return;
	}

	throw std::runtime_error("Can't open process!");
}

ADoom::~ADoom(){
	CloseHandle(DH);
}

int main()
{
	HWND	DoomWindow;
	DWORD	PID;

	DoomWindow = FindWindow(NULL, _T("Doom 95"));
	if (! DoomWindow) goto out;
	GetWindowThreadProcessId(DoomWindow, &PID);

	try
	{
		ADoom	DAim(PID);
	} catch (const std::runtime_error &err) { };

	while (1)
	{
		Sleep(1);
	}
	out:
	return 0;
}

Hem üstbilgihem de kaynak dosyayıgenişleterek işlem bellene (rM)/write(wM) okuyan işlevler oluşturacağım.
Bu amaç için iki WINAPI çağrısıkullanacağız: ReadProcessMemory() ve WriteProcessMemory().
| | | image | image

	template<typename ReadType>
	ReadType rM(DWORD, DWORD);
	BOOL wM(DWORD, PVOID, SIZE_T);

template<typename ReadType>
ReadType ADoom::rM(DWORD RAddress, DWORD Offset)
{
	ReadType Result;
	PVOID	 External = reinterpret_cast<PVOID>(RAddress + Offset);

	ReadProcessMemory(DH, External, &Result, sizeof(Result), NULL);
	return Result;
}

BOOL ADoom::wM(DWORD RAddress, PVOID LAddress, SIZE_T Size)
{
	BOOL	Status = FALSE;
	PVOID	External = reinterpret_cast<PVOID>(RAddress);

	if (WriteProcessMemory(DH, External, LAddress, Size, NULL))
	{
		Status = TRUE;
	}
	
	return Status;
}

Oyuncunun Nesne si manipülasyonunun mümkün olup olmadığını kontrol edelim:

	try
	{
		ADoom	DAim(PID);
		DWORD	Corrupt = 0x12345678, Player, PPlayer = 0x482518;

		Player = DAim.rM<DWORD>(PPlayer, 0);
		printf("Player Object @ %lX\n", Player);

		DAim.wM(PPlayer, &Corrupt, sizeof(Corrupt));
		puts("Corrupted the Player Object.");
	} catch (const std::runtime_error &err) { }


image –
Doom95.exe süreci çöküyorbaşarı.
2 bayt yamasını uygulamalı ve Oyuncunun Hedef değerini takip etmeliyiz.

	try
	{
		ADoom	DAim(PID);
		BYTE	Patch[2] = {0xEB, 0x33};
		DWORD	PAddress = 0x42264F;
		DWORD	Player, PPlayer = 0x482518;
		int		THealth;
		DWORD	OTarget = 0, Target;

		Player = DAim.rM<DWORD>(PPlayer, 0);
		printf("Player Object @ %lX\n", Player);

		printf("Applying Patch @ %lX\n", PAddress);
		DAim.wM(PAddress, &Patch[0], sizeof(Patch));

		while (true)
		{
			Target = DAim.rM<DWORD>(Player, 0x78);

			// Are we currently engaging the enemy?
			if (Target != 0)
			{
				// If yes, is it already dead?
				THealth = DAim.rM<int>(Target, 0x6C);
				if (THealth <= 0)
				{
					continue;
				}

				/*
					Uniqueness check.
				*/
				if (! OTarget || OTarget != Target)
				{
					printf("Current Target @ %lX\n", Target);
					OTarget = Target;
				}
			}
		}
	} catch (const std::runtime_error &err) { }


image –
Şimdiye kadar iyi, biz ilerleme kaydediyoruz.
İlk başta, ben tamamen Sağlık kontrolunuttum , ve ölü Monster nişan devam etti. A_FaceTarget (0041F670)hakkındaki bilgimizi kullanma nın zamanı dır.
dead

Bu EAXbir mobj_t * argüman alır , ve tek bir kontrol gerçekleştirir(EAX->target != NULL) hesaplama ve doğru açı depolamadanönce , bu bizim tarafımızda iş minimum.
Tüm yapmak için bırakılır, güvenilir bir işlev oluşturma ve depolama / uzak iş parçacığı çalıştırıyor.

VOID _declspec(naked) Reliable(VOID)
{
	__asm {
		mov eax, 0x482518 // Load PPlayer in EAX
		mov eax, [eax]    // Load Player Object in EAX
		mov edi, 0x41F670 // Indicate the FP(A_FaceTarget)
		call edi          // Call it
		ret
	}
}

Biz çalıştırılabilir derlemek ve IDA yükleyebilirsiniz.


– Hex-view, Sökme görünümü ile senkronize edilir, bu yüzden ilk ‘mov’ seçerek yapmamız gereken tek şey. image
Bu bizim görevimiz!
image

BYTE Payload[] = {0xB8, 0x18, 0x25, 0x48, 0x00, 0x8B, 0x00,
				  0xBF, 0x70, 0xF6, 0x41, 0x00, 0xFF, 0xD7,
				  0xC3};
DWORD PSize = sizeof(Payload);

Bu yapılır, biz yazmak için bir konuma ihtiyacımız var, bu Yürütülebilir / Okunabilir ve Yazılabilir çokolması gerekir.
Almak için VirtualAllocEx’iarayacağız.
biz PAGE_EXECUTE_READWRITE olarak flProtect belirtmek zorunda .
image
Başka bir yardımcı işlevi bellek ayırmakiçin kısa aM olarak adlandırılır. 

DWORD aM(SIZE_T);

DWORD ADoom::aM(SIZE_T Size)
{
	LPVOID RAddress = VirtualAllocEx(DH, NULL, Size, MEM_COMMIT | MEM_RESERVE,
					  PAGE_EXECUTE_READWRITE);
	DWORD  Cast = reinterpret_cast<DWORD>(RAddress);

	return Cast;
}

Ve sonra Doom95.exe sürecinde bir Thread yumurtlamak için bir işlev olmalıdır.
CreateRemoteThread()kullanarak WaitForSingleObject()kullanarak sonlandırmasını bekleyeceğiz.

image Adı sT olacak. image

VOID sT(DWORD);

VOID ADoom::sT(DWORD FPtr)
{
	HANDLE RT;

	RT = CreateRemoteThread(DH, NULL, 0, (LPTHREAD_START_ROUTINE) FPtr,
		 NULL, 0, NULL);

	if (RT != INVALID_HANDLE_VALUE)
	{
		WaitForSingleObject(RT, INFINITE);
	}
}

İhtiyacımız olan tek şey bu, şimdi tüm döngüyü uygulayabiliriz:

	try
	{
		ADoom	DAim(PID);
		BYTE	Patch[2] = {0xEB, 0x33};
		DWORD	PAddress = 0x42264F;
		BYTE	Payload[] = {0xB8, 0x18, 0x25, 0x48, 0x00, 0x8B, 0x00,
							 0xBF, 0x70, 0xF6, 0x41, 0x00, 0xFF, 0xD7,
							 0xC3};
		DWORD	Location, PSize = sizeof(Payload);
		DWORD	PPlayer = 0x482518, Player, Target;
		int		THealth;

		/*
			Patch:
			An unconditional JMP instruction that allows Player->target
			to be updated on every attack.
		*/
		printf("Applying Patch @ %lX\n", PAddress);
		DAim.wM(PAddress, Patch, sizeof(Patch));

		printf("Allocating Memory(%d)\n", PSize);
		Location = DAim.aM(PSize);

		printf("Storing Function @ %lX\n", Location);
		DAim.wM(Location, Payload, PSize);

		puts("[0x00sec] Aimbot starting.");

		while (TRUE)
		{
			Player = DAim.rM<DWORD>(PPlayer, 0);
			Target = DAim.rM<DWORD>(Player, 0x78);

			// Did any enemy attack us?
			if (Target != 0)
			{
				// If yes, is it still alive?
				THealth = DAim.rM<int>(Target, 0x6C);
				if (THealth > 0)
				{
					// Aim at it.
					DAim.sT(Location);
				}
			}
		}
	} catch (const std::runtime_error &err) { }


image –
Ve işe yarıyor! :smiley:

Son -unda

Bu nihai ürün almak için birçok girişimleri aldı, ama kesinlikle eğlenceliydi!
Ben bunu yapmak için bir yol bulamadım çünkü oyundan resim veya GIFdahil olamazdı, bunun için, özür dilerim.
Değişiklikler Lots güvenilirliğigaranti etmek için yapıldı , bir örnek Oyuncu nesne si iki olaygüncellenir olacaktır : Ölüm/Seviye Değişikliği.
Ve ben de gibi bazı işlevleri kurtulmakvar:

VOID GetMonsters(vector<DWORD> *M, HANDLE Proc)
{
	DWORD	First = 0x484CFC, Last = 0x484CF8;
	int		MHealth;
	UCHAR	IsMonster;

	First = rM<DWORD>(First, Proc);
	Last = rM<DWORD>(Last, Proc);
	
	do {
		IsMonster = rM<UCHAR>(First + 0x6A, Proc);
		MHealth = rM<int>(First + 0x6C, Proc);

		// Is it a monster and is it alive?
		if ((IsMonster & 0x40) && (MHealth > 0))
		{
			M->push_back(First);
		}
	} while ((First = rM<DWORD>(First + 4, Proc)) != Last);
}
4.5 2 votes
Article Rating
[Toplam: 0   Ortalama: 0/5]
Yorum Yapmak İçin Tıklayın
0 Yorum
Inline Feedbacks
View all comments
To Top
0
Would love your thoughts, please comment.x
()
x