[ iT ] Forums: Hướng dẫn cách debug game Kiếm Thế và codes minh hoạ. - [ iT ] Forums

Jump to content


Phong thu am chuyen nghiep Calvin Music

MU Phuc Hung

Làm Việc Tài Nhà

Mu Da Nang

Tuyển Nhân Viên Bán Hàng

Mu moi ra - MU SS2

Mu moi ra - MU Phuong Hoang

Mu moi ra - Thien Bao

  • 2 Trang +
  • 1
  • 2
  • Bạn không thể gửi chủ đề mới
  • Bạn không thể gửi trả lời cho chủ đề này

Hướng dẫn cách debug game Kiếm Thế và codes minh hoạ. Đánh Giá: ***-- 1 Bình chọn

#1 User is offline   Huỳnh Văn Thâm 

  • Nhóm: VIP
  • Bài Viết: 2364
  • Gia Nhập: 09-October 07
  • Thạc sĩ CSTH
  • PipPipPipPipPipPip

Gửi vào 07 October 2009 - 04:17 PM

Mình là dân gà nên ai là dân gà giống mình thì chúng ta đi tuần tự từ căn bản đến nâng cao nhé, chứ mới vô mà đọc 3 cái này thì chỉ có nước khùng :hehe

Download CheatEngine55 chương trình này dùng để debug vùng nhớ.

Trước tiên mình xin góp một bài rất là căn bản là dùng CheatEngine55 để mà debug ra địa chỉ vùng nhớ nhé.

Dùng CheatEngine để debug địa chỉ vùng nhớ

1. Chạy chương trinh game lên và đăng nhập vào game
Posted Image
H1. Nhân vật proakam của mình


2. Chạy chương trình CheatEngine lên và vào chọn menu Process->game.exe để chọn Kiếm Thế
Posted Image
H2. Chọn Kiếm Thế


3. Gõ giá trị máu của bạn vào textbox value. Ví dụ của mình là 708
Posted Image
H3. Nhập giá trị máu 708/708 vào textbox Value


4. Bấm vào nút "First Scan" để mà bắt đầu tìm các vùng nhớ có giá trị 708. Khi nào nó tìm xong thì sẽ hiện thị tất cả các vùng nhớ có giá trị 708 vào "Found:xxx". Nó thường có rất nhiều kết quả cho lần "First Scan"
Posted Image
H4. Kết quả của "First Scan" vùng nhớ có giá trị 708


5. Vì "First Scan" nó cho kết quả nhiều quá do đó chung ta phải lọc bớt các giá trị không đúng. Bạn vào game đem con tướng cho nó đi đánh quái để bớt đi một lượng máu (tìm con nào yếu thôi, không thì nó đánh chết đó).
Posted Image
H5. Cho quái đánh mất bớt một lượng máu


6. Quay lại chương trình CheatEngine ngồi canh gỏ vào số lượng máu còn lại rồi sau đó bấm "Next Scan", lúc đó CheatEngine sẽ tìm trong những vùng nhớ trong lần "First Scan" xem có vùng nhớ nào có giá trị này không. Ví dụ mình còn 593 mình gỏ vào textbox value giá trị 593 sau đó bấm "Next Scan". Lúc đó nó cho mình 2 giá trị. Và bạn sẽ thấy 2 giá trị (value) này sẽ tăng dần theo số lượng máu được phục hồi trong game. Như vậy là OK rồi đó
Posted Image
H6. "Next Scan" với số máu là 593


7. Giờ mình sẽ hướng dẫn các bạn cách tìm địa chỉ vùng nhớ KNPC_BASE_ADD. Bạn double click vào 2 dòng kết quá tìm được (trong Found:2 đó), khi đó nó sẻ thêm 2 dòng này vào cái lưới phía bên dưới. Bạn kích chuột phải vào một dòng nào đó chọn "Find out what accesses this address" để nó mở cửa sổ "The following opcodes accessed the select..." để theo giỏi sự truy cập vùng nhớ này.
Posted Image
H7. Theo giỏi sự truy cập vùng nhớ 0284B368


8. Giờ quay lại game chơi, ví dụ cho nhân vật nó chạy tới chạy lui hay làm gì đó khi nào trong cửa sổ "The following opcodes accessed the select..." có thêm các dòng lệnh asm mov.... thì dừng lại vào xem nhé.
Posted Image
H8. Cửa sổ theo giỏi sự truy cập vùng nhớ 0284B368


9. Giờ bạn double click vào một dòng nào đó (những dòng lệnh mov mới đó). Nó sẽ mở cửa sổ Extra Info nó cho biết thông tin chi tiết của dòng lệnh đó
Posted Image
H9. Thông tin chi tiết của dòng lệnh mov ecx,[eax+edx+00000338]


10. Hãy chú ý nhé: Dòng lệnh phía trên (dòng được bôi đỏ ở H9) nó chính là địa chỉ KNPC_BASE_ADD.

Thế là có một chút cơ sở để debug vùng nhớ rồi đó, các bác cố mà nhai ASM để mà đọc hiểu hơn (mình đang nhai muốn đuối quá :busy ).

Chúc các bạn thành công nhé :bong
0

#2 User is offline   Huỳnh Văn Thâm 

  • Nhóm: VIP
  • Bài Viết: 2364
  • Gia Nhập: 09-October 07
  • Thạc sĩ CSTH
  • PipPipPipPipPipPip

Gửi vào 07 October 2009 - 04:18 PM

Nhớ đọc bài debug trước rồi hãy đọc bài này nha các bác, đừng vội quá rồi nhức đầu ráng chịu đó nha :d
Tiếp theo mình sẽ hướng dẫn các bạn cách đọc thông tin máu nhé.

Cách đọc thông tin máu bằng VB6.0

1. Quay lại hình này nhé.
Posted Image
Bạn hãy để ý dòng lệnh sau:
mov eax, [0078aeac]
mov ecx, [eax+edx+00000338]

Trước tiên nó move giá trị [0078aeac] vào thanh gi EAX, sau đó nó move giá trị [eax+edx+00000338] vào thanh gi ecx như vậy bạn phải. Biết giá trị của các thanh ghi eax, edx
- Muốn biết giá trị của thanh ghi eax là bao nhiêu thì bạn phải đọc giá trị tại vùng nhớ [0078aeac] lấy ra 4 byte. (trong hình nó chính là 02840024)
- Muốn biết giá trị thanh ghi edx thì bạn nhìn vào hình đó nó chính là B00C
- Như vậy là bạn đã biết cách lấy thông tin máu rồi đó (Đọc giá trị vùng nhớ [02840024 + B00C + 00000338])

2. Codes VB lấy thông tin máu
Const PROCESS_VM_OPERATION As Long = &H8
Const PROCESS_VM_READ As Long = &H10
Const PROCESS_VM_WRITE As Long = &H20
Const PROCESS_ALL_ACCESS As Long = &H1F0FFF

Const NPC_BASE_ADD = &H78AEAC
Const NPC_DATA_SIZE = &HB00C&
Const NPC_CURLIFE_OFFSET = &H338
Const NPC_MAXLIFE_OFFSET As Long = &H334

Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" _
	(ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function GetWindowThreadProcessId Lib "user32" _
	(ByVal hwnd As Long, lpdwProcessId As Long) As Long
Private Declare Function OpenProcess Lib "kernel32" _
	(ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
Private Declare Function ReadProcessMemory Lib "kernel32" _
	(ByVal hProcess As Long, ByVal lpBaseAddress As Any, lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long
Private Declare Function WriteProcessMemory Lib "kernel32" _
	(ByVal hProcess As Long, ByVal lpBaseAddress As Any, ByVal lpBuffer As Any, ByVal nSize As Long, ByVal lpNumberOfBytesWritten As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" _
	(ByVal hObject As Long) As Long

Private Sub Form_Load()
	Dim hKTWindow&, dwProcessId&, dwThreatID&, hProcess&
	Dim lpBaseAdd&, lpCurAdd&, bRead As Boolean
	Dim dwCurHP&
	
	hKTWindow = FindWindow("_Class", vbNullString)
	If hKTWindow = 0 Then Exit Sub
	GetWindowThreadProcessId hKTWindow, dwProcessId
	hProcess = OpenProcess(PROCESS_VM_READ, False, dwProcessId)
	
	'Get Current HP
	bRead = ReadProcessMemory(hProcess, NPC_BASE_ADD, lpBaseAdd, 4, 0&) '
	If bRead = True Then
		lpCurAdd = lpBaseAdd + NPC_CURLIFE_OFFSET + NPC_DATA_SIZE
		bRead = ReadProcessMemory(hProcess, lpCurAdd, dwCurHP, 4, 0&)
		If bRead = True Then
			MsgBox CStr(dwCurHP)
		Else
			''
		End If
	End If
	Call CloseHandle(hProcess)
	End
End Sub



Cách đọc thông tin máu bằng C#

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace WindowsApplication2
{
	public partial class Form1 : Form
	{
		[DllImport("user32", EntryPoint = "FindWindowA", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
		public static extern int FindWindow(string lpClassName, string lpWindowName);
		[DllImport("user32", EntryPoint = "FindWindowExA", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
		public static extern int FindWindowEx(int hWnd1, int hWnd2, string lpsz1, string lpsz2);		
		[DllImport("user32.dll")]
		public static extern uint GetWindowThreadProcessId(int hWnd, out int lpdwProcessId);
		[DllImport("kernel32.dll")]
		public static extern int OpenProcess(int dwDesiredAccess, bool bInheritHandle, int dwProcessId);

		[DllImport("kernel32.dll")]
		static extern bool ReadProcessMemory(
			IntPtr hProcess,
			IntPtr lpBaseAddress,
			byte[] lpBuffer,
			int dwSize,
			int lpNumberOfBytesWritten
		); 
	

		[DllImport("kernel32.dll")]
		public static extern bool WriteProcessMemory(int hProcess, int lpBaseAddress, byte lpBuffer, int nSize, int lpNumberOfBytesWritten);

		private int PROCESS_VM_OPERATION = 0x8;
		private int PROCESS_VM_READ = 0x10;
		private int PROCESS_VM_WRITE = 0x20;
		private int PROCESS_ALL_ACCESS = 0x1F0FFF;

		private int NPC_BASE_ADD = 0x78AEAC;
		private int NPC_DATA_SIZE = 0xB00C;
		private int NPC_CURLIFE_OFFSET = 0x338;
		private int NPC_NAME_OFFSET = 0xAC6C;

		private int NPC_MAXLIFE_OFFSET = 0x334;

		public Form1()
		{
			InitializeComponent();
		}

		private void Form1_Load(object sender, EventArgs e)
		{
			int hKTWindow, dwProcessId, dwThreatID, hProcess;
			int lpBaseAdd, lpCurAdd;
			bool bRead;
			int dwCurHP, dwMaxHP;
			string szName;
			hKTWindow = FindWindow("_Class", null);
			if (hKTWindow == 0) Application.Exit();
			GetWindowThreadProcessId( hKTWindow,out dwProcessId);
			hProcess = OpenProcess(PROCESS_VM_READ, false, dwProcessId);
			
			byte[] buffer = new byte[4];
			bRead = ReadProcessMemory((IntPtr)hProcess, (IntPtr)NPC_BASE_ADD, buffer, buffer.Length, 0);
			lpBaseAdd = (int)BitConverter.ToUInt32(buffer, 0);
			lpCurAdd = lpBaseAdd + NPC_CURLIFE_OFFSET + NPC_DATA_SIZE;

			bRead = ReadProcessMemory((IntPtr)hProcess, (IntPtr)lpCurAdd, buffer, buffer.Length, 0);
			dwCurHP = (int)BitConverter.ToUInt32(buffer, 0);
			MessageBox.Show(dwCurHP.ToString());
		}
	}
}

Chúc các bạn thành công

Bài viết này được chỉnh sửa bởi Huỳnh Văn Thâm: 12 October 2009 - 07:55 AM

0

#3 User is offline   Huỳnh Văn Thâm 

  • Nhóm: VIP
  • Bài Viết: 2364
  • Gia Nhập: 09-October 07
  • Thạc sĩ CSTH
  • PipPipPipPipPipPip

Gửi vào 07 October 2009 - 04:20 PM

Lấy thông tin máu cho từng nhân vật trong game Kiếm Thế

Const PROCESS_VM_OPERATION As Long = &H8
Const PROCESS_VM_READ As Long = &H10
Const PROCESS_VM_WRITE As Long = &H20
Const PROCESS_ALL_ACCESS As Long = &H1F0FFF

Const NPC_BASE_ADD = &H78AEAC
Const NPC_DATA_SIZE = &HB00C&
Const NPC_CURLIFE_OFFSET = &H338
Const NPC_MAXLIFE_OFFSET As Long = &H334

Const GW_HWNDNEXT = 2
Const MAX_PATH = 260

Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" _
	(ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function GetWindowThreadProcessId Lib "user32" _
	(ByVal hwnd As Long, lpdwProcessId As Long) As Long
Private Declare Function OpenProcess Lib "kernel32" _
	(ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
Private Declare Function ReadProcessMemory Lib "kernel32" _
	(ByVal hProcess As Long, ByVal lpBaseAddress As Any, lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long
Private Declare Function WriteProcessMemory Lib "kernel32" _
	(ByVal hProcess As Long, ByVal lpBaseAddress As Any, ByVal lpBuffer As Any, ByVal nSize As Long, ByVal lpNumberOfBytesWritten As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" _
	(ByVal hObject As Long) As Long
Private Declare Function FindWindowLong Lib "user32" Alias "FindWindowA" _
	(ByVal lpClassName As Long, ByVal lpWindowName As Long) As Long
Private Declare Function GetWindow Lib "user32" _
	(ByVal hwnd As Long, ByVal wCmd As Long) As Long
Private Declare Function GetClassName Lib "user32" Alias "GetClassNameA" _
	(ByVal hwnd As Long, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long
Private Declare Function GetWindowText Lib "user32" Alias "GetWindowTextA" _
	(ByVal hwnd As Long, ByVal lpString As String, ByVal cch As Long) As Long

Private Sub Form_Load()
	GetALLHP
End Sub
Public Function GetALLHP()
	Dim sWClass$, sWCaption$
	
	Dim hwnd As Long
	
	hwnd = FindWindowLong(ByVal 0&, ByVal 0&)
	Do While hwnd <> 0
		sWClass = GetClassHandle(hwnd)
		sWCaption = GetCaptionHandle(hwnd)
		If sWClass = "_Class" And Len(sWCaption) > 2 Then
			If Mid(sWCaption, 1, 2) = "Ki" Then
				MsgBox GetHP(hwnd)
			End If
		End If
		
		hwnd = GetWindow(hwnd, GW_HWNDNEXT)
	Loop
End Function

Public Function GetHP(hKTWindow As Long) As Long
	Dim dwProcessId&, dwThreatID&, hProcess&
	Dim lpBaseAdd&, lpCurAdd&, bRead As Boolean
	Dim dwCurHP&
	
	GetWindowThreadProcessId hKTWindow, dwProcessId
	hProcess = OpenProcess(PROCESS_VM_READ, False, dwProcessId)
	
	'Get Current HP
	bRead = ReadProcessMemory(hProcess, NPC_BASE_ADD, lpBaseAdd, 4, 0&) '
	If bRead = True Then
		lpCurAdd = lpBaseAdd + NPC_CURLIFE_OFFSET + NPC_DATA_SIZE
		bRead = ReadProcessMemory(hProcess, lpCurAdd, dwCurHP, 4, 0&)
	End If
	Call CloseHandle(hProcess)
	GetHP = dwCurHP
End Function

Public Function GetClassHandle(lhnd As Long) As String
	Dim strClass As String
	strClass = Space$(MAX_PATH)
	Call GetClassName(lhnd, strClass, 255)
	strClass = Left$(strClass, InStr(strClass, vbNullChar) - 1) '
	GetClassHandle = strClass
End Function

Public Function GetCaptionHandle(lhnd As Long) As String
	Dim strCaption As String
	lStrLen = MAX_PATH
	strCaption = Space$(MAX_PATH)
	Call GetWindowText(lHandle, strCaption, lStrLen)
	lStrLen = GetWindowText(lhnd, strCaption, lStrLen)
	strCaption = Left$(strCaption, lStrLen) '
	GetCaptionHandle = strCaption
End Function

0

#4 User is offline   Huỳnh Văn Thâm 

  • Nhóm: VIP
  • Bài Viết: 2364
  • Gia Nhập: 09-October 07
  • Thạc sĩ CSTH
  • PipPipPipPipPipPip

Gửi vào 12 October 2009 - 03:19 PM

Những ví dụ trên chỉ là phần đọc dữ liệu tại một vùng nhớ nào đó thôi, cái quan trọng của chúng ta là phần hook vào game Kiếm Thế để gọi các function asm (assembly)

Cách tạo file Hook cho một handle (window handle)

I. Nhận sét: Theo mình đọc hiểu từ các ví dụ của các anh và các bạn đã viết hook thì thật ra nó chỉ là một function bắt các giá trị gởi vào của hàm Sendmessage hay Postmessage và dựa vào giá trị gởi vào của 2 hàm này mà sử lý. Và cái function (hook) này gọi các functions của asm (assembly) là chủ yếu.

II. Mình sẽ hướng dẫn các bạn cách tạo file KTHook.dll trong VS C++ 6.0
1. Trong VS C++ 6.0 muốn tạo một file dll dựa vào 3 tập tin chính
- Tập tin .h : Giúp bạn khai báo các functions (hàm) hay các properies (thuộc tính, biến) cần thiết
- Tập tin .cpp : Tập tin này dùng để định nghĩa cụ thể các functions được khai báo trong tập tin .h
- Tạp tin .def: Tập tin này dùng để export (đưa ra bên ngoài) những functions nào cần public (bên ngoài dùng được) cho các ứng dụng khác gọi các functions được khai báo trong này.

2. Cách tạo một project tạo tập tin dll
- Chạy chương trình "Microsoft Visual C++ 6.0" -> "File" -> "New" lúc này nó sẻ mở cửa sổ New lên, vì chúng ta muốn tạo tập tin DLL do đó chúng ta chọn "Win32 Dynamic - Link Library" (nó viết tắt là DLL đó bạn). Bạn gỏ vào "Project Name" tên ứng dụng của bạn (Ví dụ là KTHook), bạn chọn thư mục lưu trữ project của bạn tại "Location". Và các thông tin khác thì cứ để mặt định.
Posted Image
- Tiếp theo bạn bấm vào nút OK (trên cửa sổ New). Lúc này nó sẻ đưa bạn đến cửa sổ "Win 32 Dynamic-Link Library - Step 1 of 1" Tại đây có 3 sự lựa chọn
*1 An empty DLL project: Cái này thì nó sẻ tạo một project trống (không có gì) bạn tự thêm các tập tin cần thiết theo ý mình. Cách này khi nào bạn hiểu thì hãy làm nha.
*2 A simple DLL project: Cách này thì nó sẽ tạo giúp bạn 2 tập tin .h và .cpp còn tập tin .def thì bạn tự thêm vào (theo mình cách này là đơn giản nhất, nên chọn cách này để hiều cách 1 và 3 )
*3 A DLL that export some symbols: Cách này thì nó tạo hết cho bạn các tập tin .h, .cpp và phần export (phần nằm trong tập tin .def).

Posted Image
- Bạn hãy chọn vào "A simple DLL project" sau đó bấm "Finish" lúc này nó sẽ thông báo cho bạn biết là nó thêm hàm DllMain vào trong tập tin KTHook.cpp và tạo thêm phần Header Stdafx.h và Stdafx.cpp vào trong project của bạn (Header dùng để khai báo các thư viện của Win32). Bạn bấm vào nút "OK". Lúc này coi như phần tạo project tạo tập tin dll coi như đã hoàn thành, và tiếp theo chỉ là codes.
- Giờ bạn hãy thêm tập tin .def vào project của bạn: Chọn File->New->Text File đánh vào file name là KTHook.def sau đó bấm OK
Posted Image
- Nếu trong project của bạn chưa có tập tin KTHook.h thì bạn hãy thêm vào bằng cách: Chọn File->New->C/C++ Header File gõ vào File name là KTHook.h
Posted Image

3. Giờ mình sẻ hướng dẫn cách codes tập tin KTHook.dll dựa vào các codes của các anh và các bạn đã chia sẻ
- Trong các dll (hook.dll) của các anh và các bác chia sẻ thì nó có 3 hàm (functions) chính đó là InjectDll (dùng để khởi tạo Hook), UnmapDll (Giải phóng hook), GetMsg (lấy giá trị đăng ký hook trong windows - nó là hằng số khi bạn đăng ký Hook thì giá trị này sẻ được khởi tạo trong windows)
- Trước tiên bạn vào tập tin KTHook.h khai báo 3 functions này
int __stdcall InjectDll(HWND hWnd);
int __stdcall UnmapDll(HWND hWnd);
UINT __stdcall GetMsg();

- Tiếp theo bạn vào tập tin KTHook.cpp thêm dòng #include "KTHook.h" để khai báo cho tập tin KTHook.cpp biết tập tin KTHoo.h (lúc này những gì khai báo trong KTHook.h thì trong KTHook.cpp đều truy xuất được). Sau đó bạn hãy định nghĩa tạm thời 3 functions này trong tập tin KTHook.cpp như sau.
int __stdcall InjectDll(HWND hWnd)
{
	return 1;
}
int __stdcall UnmapDll(HWND hWnd)
{
	return 1;
}
UINT __stdcall GetMsg()
{
	return 1;
}

- Giờ bạn quay qua tập tin KTHook.def để export 3 functions này cho các ứng dụng khác gọi được 3 functions. Bạn khai báo như sau:
LIBRARY KTHook
DESCRIPTION 

EXPORTS
	InjectDll
	UnmapDll
	GetMsg

trong đó LIBRARY KTHook (tên lib của bạn bạn muốn đặt tên gì thì đặt). DESCRIPTION (mô tả sơ qua cái dll của bạn). EXPORTS cái này là quan trọng nhất bạn muốn export ra những functions nào cần public cho người ta dùng thì hãy khai bào ở đây (như ví dụ ở trên thì nó chính là 3 function InjectDll, UnmapDll, GetMsg)

*Cuối cùng ta được:
KTHook.h
int __stdcall InjectDll(HWND hWnd);
int __stdcall UnmapDll(HWND hWnd);
UINT __stdcall GetMsg();

KTHook.cpp
#include "stdafx.h"
#include "KTHook.h"

BOOL APIENTRY DllMain(HANDLE hModule, DWORD uReason, LPVOID lpReserved)
{
	return TRUE;
}
int __stdcall InjectDll(HWND hWnd)
{	
	return 1;
}
int __stdcall UnmapDll(HWND hWnd)
{	
	return 1;
}
UINT __stdcall GetMsg()
{
	return 1;
}


KTHook.def
LIBRARY KTHook
DESCRIPTION 

EXPORTS
	InjectDll
	UnmapDll
	GetMsg

- Giờ bạn thử Build thử xem nó có bị lỗi gì hay không trước khi build hãy vào: Project->Settings->link trong Ouput File name bạn gõ vào tên tập tin output theo ý bạn (ví dụ là KTHook.dll)
Posted Image




(Còn nữa)

Bài viết này được chỉnh sửa bởi Huỳnh Văn Thâm: 12 October 2009 - 03:44 PM

0

#5 User is offline   Huỳnh Văn Thâm 

  • Nhóm: VIP
  • Bài Viết: 2364
  • Gia Nhập: 09-October 07
  • Thạc sĩ CSTH
  • PipPipPipPipPipPip

Gửi vào 12 October 2009 - 03:42 PM

(Tiếp theo)
Định nghĩa 3 hàm InjectDll, UnMapDll, GetMsg

Codes của các anh và các bạn chia sẻ như sau, mình chỉ giải thích cho các bạn hiểu rõ thêm thôi. Vì toàn bô codes đã được các anh và các bạn làm theo chuẩn hết rồi, chúng ta chỉ dựa vào cái chuẩn này mà phát triển cho ứng dụng của mình mà thôi.

Mở tập tin KTHook.cpp và bạn codes như sau: Đây là codes căn bản nhất của một Hook vào một windown handle nào đó được chỉ định trong hàm InjectDll.
// KTHook.cpp : Defines the entry point for the DLL application.
//

#include "stdafx.h"
#include "KTHook.h"


HINSTANCE			hDll;

const UINT WM_HOOK_WRITE = RegisterWindowMessage("WM_HOOK_WRITE");
const UINT WM_HOOKEX = RegisterWindowMessage("WM_HOOKEX_RK");

#define pCW ((CWPSTRUCT*)lParam)
WNDPROC				OldWndProc = NULL;
LRESULT CALLBACK	NewWndProc(HWND,UINT,WPARAM,LPARAM);

BOOL bHooked = 0;


BOOL APIENTRY DllMain(HANDLE hModule, DWORD uReason, LPVOID lpReserved)
{
	if(uReason == DLL_PROCESS_ATTACH)
	{
		hDll = (HINSTANCE) hModule;
		DisableThreadLibraryCalls(hDll);
	}
	return TRUE;
}

LRESULT HookProc (int nCode, WPARAM wParam, LPARAM lParam)
{

	HWND hVLWnd = pCW->hwnd;
	HHOOK hHook = (HHOOK)pCW->wParam;
	if(nCode<0)		goto CALL_NEXTHOOK;
	if((pCW->message == WM_HOOKEX) && pCW->lParam)
	{
		UnhookWindowsHookEx(hHook);
		if (bHooked)
			goto CALL_NEXTHOOK;
		char lib_name[MAX_PATH];
		GetModuleFileName(hDll, lib_name, MAX_PATH);
		if(!LoadLibrary(lib_name))
			goto CALL_NEXTHOOK;		
		OldWndProc = (WNDPROC)SetWindowLong(hVLWnd, GWL_WNDPROC, (LONG)NewWndProc);
		if(OldWndProc==NULL) {
			FreeLibrary(hDll);
		}
		else
		{
			bHooked = TRUE;
		}
	}
	else if(pCW->message == WM_HOOKEX) 
	{
		UnhookWindowsHookEx(hHook);
		if (!bHooked)
			goto CALL_NEXTHOOK;
		if(!SetWindowLong(hVLWnd, GWL_WNDPROC, (LONG)OldWndProc))
			goto CALL_NEXTHOOK;
		FreeLibrary(hDll);
		bHooked = FALSE;
	}
CALL_NEXTHOOK:
	return CallNextHookEx(hHook, nCode, wParam, lParam);
}

LRESULT CALLBACK NewWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{	
	if (uMsg==WM_HOOK_WRITE) 
	{		
		switch (wParam)
		{
//Bạn hãy sử lý các wParam  và lParam nhận được từ hàm Sendmessage và Postmessage
			case 1:
				break;
		}		
	}

	return CallWindowProc(OldWndProc, hWnd, uMsg, wParam, lParam);
}

int __stdcall InjectDll(HWND hWnd)
{
	if (!IsWindow(hWnd))
		return 0;
	HHOOK hHook = SetWindowsHookEx(WH_CALLWNDPROC,(HOOKPROC)HookProc, hDll, GetWindowThreadProcessId(hWnd,NULL));
	if(hHook==NULL)
		return 0;
	SendMessage(hWnd, WM_HOOKEX, WPARAM(hHook), 1);

	return 1;
}
int __stdcall UnmapDll(HWND hWnd)
{
	if (!IsWindow(hWnd))
		return 0;
	HHOOK hHook = SetWindowsHookEx(WH_CALLWNDPROC,(HOOKPROC)HookProc, hDll, GetWindowThreadProcessId(hWnd,NULL));
	if(hHook==NULL)
		return 0;
	SendMessage(hWnd, WM_HOOKEX, (WPARAM)hHook, 0);
	return 1;
}
UINT __stdcall GetMsg()
{
	return WM_HOOK_WRITE;
}


************Giải thích codes phía trên************
- HINSTANCE hDll; Vì chúng ta dùng DLL instances (DLL dùng chung) do đó khai báo biến này để sử lý trong hàm DllMain khi mà có DLL_PROCESS_ATTACH xảy ra (bạn có thể tham khảo ở đây để hiểu rõ hơn - mình cũng chưa hiểu rõ chổ này cho lắm :bong )
- 2 khai báo phía dưới là đăng ký cái dll của bạn cho windows
const UINT WM_HOOK_WRITE = RegisterWindowMessage("WM_HOOK_WRITE");
const UINT WM_HOOKEX = RegisterWindowMessage("WM_HOOKEX_RK");

- Giờ thì mình có giải thích nữa thì cũng chỉ giải thích các hàm API là cùng :( do đó các bạn cố tìm hiểucác hàm API mà hiểu thêm :( . Mình chỉ nói thêm là hãy chú ý 2 hàm InjectDll(HWND hWnd) và UnmapDll(HWND hWnd) gần như giống nhau hoàn toàn chỉ có khác ở chổ là SendMessage(hWnd, WM_HOOKEX, WPARAM(hHook), 1); và SendMessage(hWnd, WM_HOOKEX, WPARAM(hHook), 0);

- Coi như bài viết tới đây xin tạm dừng huy vọng nó sẽ giúp các bạn newbie như mình hiểu một cách tương đối về cách viết một Hook bằng C++ như thế nào

- Xin chân thành cảm ơn các anh và các bạn bên VLTK Programer đã chia sẽ codes.

(Sắp tới mình sẽ hướng dẫn các bạn cách sử lý các wParam, lParam trong hàm NewWndProc để mà gọi các asm như thế nào)

Vì là newbie nên có thể bài viết chỉ ở mức newbie mong anh em thông cảm :d có chổ nào sai sót hay góp ý xin cho ý kiến cụ thể đừng nói chung để mà mình còn biết đường cải thiện nó :d
Chúc các bạn thành công
Mr. Thâm

Tệp Đính Kèm


Bài viết này được chỉnh sửa bởi Huỳnh Văn Thâm: 12 October 2009 - 04:52 PM

0

#6 User is offline   ragnakrorn77 

  • Nhóm: Newbies
  • Bài Viết: 4
  • Gia Nhập: 07-June 08
  • Thành viên mới

Gửi vào 20 November 2009 - 08:10 PM

Vì chưa đủ bài viết , nên em post trong đây , vì đây là game TLBB , đừng xóa bài em nha
Ai giúp em với , em scan ra bước này , tới 3 dòng address màu xanh
Posted Image
thấy vậy em scan tiếp thì ra 1 đống address màu xanh , em dùng pointer scan dòng address thứ nhất trong đống address màu xanh rồi sau đó Find out what access this pointer thì không ra gì cả.Lay hay mấy bữa giờ.Ai có kinh nghiệm giúp em với.
0

#7 User is offline   DoMinhTho 

  • Nhóm: Member
  • Bài Viết: 35
  • Gia Nhập: 31-December 06
  • Thành viên mới

Gửi vào 29 November 2009 - 10:31 PM

hehe,bài viết này hay nè.Thank Mr Thâm nhé.Mình cũng đang học qua C++ và tìm hiểu Hook.Mình thấy đây là 1 lĩnh vực rất hay.Các bài viết của tiền bối thì có vẻ chung chung và đi nhanh quá.Step by step thế này coi bộ dễ nuốt hơn.Ước gì có 1 chuyên đề nói về kỹ thuật này nhỉ.
Thank bác Thâm 1 lần nữa.Tiếp nào bác :X.

Bài viết này được chỉnh sửa bởi DoMinhTho: 30 November 2009 - 11:16 AM

0

#8 User is offline   dacminhm 

  • Nhóm: Newbies
  • Bài Viết: 26
  • Gia Nhập: 14-June 09
  • Thành viên mới

Gửi vào 04 December 2009 - 04:31 PM

Làm theo tất cả các bước để được file hook nhưng để làm gì với nó vậy :-/
0

#9 User is offline   DUY04 

  • Nhóm: Newbies
  • Bài Viết: 21
  • Gia Nhập: 11-November 09
  • Thành viên mới

Gửi vào 08 December 2009 - 06:57 AM

bài hay lắm, ban làm tiếp cái hướng dãn tìm MOB ID ADDRESS bằng CE chính xác nhất đê ! mình rất muốn học :ay:
0

#10 User is offline   tieuquy07 

  • Nhóm: VIP
  • Bài Viết: 110
  • Gia Nhập: 17-March 07
  • Trình độ A CSTH
  • PipPip

Gửi vào 20 December 2009 - 03:59 PM

Bài rất hay và rất bổ ích !
Đề nghị MOD đưa lên phần đầu box
- Tiếp đi bạn ơi ...........
0

#11 User is offline   phuong phi ho 

  • Nhóm: Newbies
  • Bài Viết: 35
  • Gia Nhập: 22-December 09
  • Thành viên mới

Gửi vào 31 December 2009 - 05:36 PM

Và cuối cùng là chúng ta có đc cheat regent HP giống như game PTV (@hắc regent máu hay còn gọi là bất tử) ko?
0

#12 User is offline   TITA 

  • Nhóm: Newbies
  • Bài Viết: 1
  • Gia Nhập: 16-December 09
  • Thành viên mới

Gửi vào 22 January 2010 - 03:03 PM

bạn cho nh hoi y nghia va may tham so cua cac biến này được lấy từ đâu : va cho mình 1 vidj lun nha :phu

private int PROCESS_VM_OPERATION
private int PROCESS_VM_READ
private int PROCESS_VM_WRITE
private int PROCESS_ALL_ACCESS
private int NPC_NAME_OFFSET
private int NPC_MAXLIFE_OFFSET

và cho moi ý nghĩa cua giá tri _Class trong hàm nay : FindWindow("_Class", null);
nó la gì tến handle cua cua ung dang dang active hay là gì ..

mong bạn giúp đỡ

Cam ơn nhièu .!
0

#13 User is offline   DepTraiMaEm 

  • Nhóm: Newbies
  • Bài Viết: 47
  • Gia Nhập: 25-December 09
  • Căn bản tin học tốt
  • Pip

Gửi vào 13 March 2010 - 12:38 PM

Bạn nào giúp mình cái :


Mình muốn đếm 1 vật phẩm nào đó trong hành trang của mình có được bao nhiêu cái thì phải debug làm sao.

Mình dùng CE, và artmoney tìm địa chỉ bộ nhớ về số lượng item trong hành trang. nhưng địa chỉ thì cứ thay đổi liên tục. mình nghĩ item nó không nằm 1 chỗ mà nó nằm nhiều nơi trong hành trang nên mình tìm không được address của nó.



Bạn biết thì gợi ý cho mình làm thử nhé.

Cảm ơn nhiều lắm.

Bài viết này được chỉnh sửa bởi DepTraiMaEm: 13 March 2010 - 12:43 PM

0

#14 User is offline   34324 

  • Nhóm: Advance Member
  • Bài Viết: 13
  • Gia Nhập: 29-July 06
  • Thành viên mới

Gửi vào 19 June 2010 - 01:49 PM

EAX=00000002
EBX=00000000
ECX=00A00002
EDX=09D30002
ESI=00A25156
EDI=000009D3
EBP=0012CA10
ESP=0012C810
EIP=004C1175

Probable base pointer =00A43AC4

004c1167 - mov cx,[ebp+6c]
004c116b - movzx eax,cx
004c116e - mov [eax*4+00a43ac4],edi
004c1175 - cmp cx,04
004c1179 - jne 004c119d


các bạn cho mình hỏi nếu code như vầy thì làm sao để kiếm base address. nó có phải là 00A43AC4
0

#15 User is offline   red_evilspirit 

  • Nhóm: Newbies
  • Bài Viết: 5
  • Gia Nhập: 04-August 10
  • Thành viên mới

Gửi vào 17 August 2010 - 11:58 AM

Tạo được file .dll thì làm thế nào để tạo file .exe để gọi .dll đấy ?
0

#16 User is offline   tctruc 

  • Nhóm: Member
  • Bài Viết: 58
  • Gia Nhập: 06-February 07
  • Căn bản tin học tốt
  • Pip

Gửi vào 25 November 2010 - 04:04 PM

View PostHuỳnh Văn Thâm, on 07 October 2009 - 04:18 PM, said:

Nhớ đọc bài debug trước rồi hãy đọc bài này nha các bác, đừng vội quá rồi nhức đầu ráng chịu đó nha <img src='http://forum.cuasotinhoc.vn/public/style_emoticons/<#EMO_DIR#>/4.gif' class='bbc_emoticon' alt=':d' />
Tiếp theo mình sẽ hướng dẫn các bạn cách đọc thông tin máu nhé.

Cách đọc thông tin máu bằng VB6.0

1. Quay lại hình này nhé.
Posted Image
Bạn hãy để ý dòng lệnh sau:
mov eax, [0078aeac]
mov ecx, [eax+edx+00000338]

Trước tiên nó move giá trị [0078aeac] vào thanh gi EAX, sau đó nó move giá trị [eax+edx+00000338] vào thanh gi ecx như vậy bạn phải. Biết giá trị của các thanh ghi eax, edx
- Muốn biết giá trị của thanh ghi eax là bao nhiêu thì bạn phải đọc giá trị tại vùng nhớ [0078aeac] lấy ra 4 byte. (trong hình nó chính là 02840024)
- Muốn biết giá trị thanh ghi edx thì bạn nhìn vào hình đó nó chính là B00C
- Như vậy là bạn đã biết cách lấy thông tin máu rồi đó (Đọc giá trị vùng nhớ [02840024 + B00C + 00000338])

2. Codes VB lấy thông tin máu
Const PROCESS_VM_OPERATION As Long = &H8
Const PROCESS_VM_READ As Long = &H10
Const PROCESS_VM_WRITE As Long = &H20
Const PROCESS_ALL_ACCESS As Long = &H1F0FFF

Const NPC_BASE_ADD = &H78AEAC
Const NPC_DATA_SIZE = &HB00C&
Const NPC_CURLIFE_OFFSET = &H338
Const NPC_MAXLIFE_OFFSET As Long = &H334

Private Declare Function FindWindow Lib "user32" Alias "FindWindowA" _
	(ByVal lpClassName As String, ByVal lpWindowName As String) As Long
Private Declare Function GetWindowThreadProcessId Lib "user32" _
	(ByVal hwnd As Long, lpdwProcessId As Long) As Long
Private Declare Function OpenProcess Lib "kernel32" _
	(ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal dwProcessId As Long) As Long
Private Declare Function ReadProcessMemory Lib "kernel32" _
	(ByVal hProcess As Long, ByVal lpBaseAddress As Any, lpBuffer As Any, ByVal nSize As Long, lpNumberOfBytesWritten As Long) As Long
Private Declare Function WriteProcessMemory Lib "kernel32" _
	(ByVal hProcess As Long, ByVal lpBaseAddress As Any, ByVal lpBuffer As Any, ByVal nSize As Long, ByVal lpNumberOfBytesWritten As Long) As Long
Private Declare Function CloseHandle Lib "kernel32" _
	(ByVal hObject As Long) As Long

Private Sub Form_Load()
	Dim hKTWindow&, dwProcessId&, dwThreatID&, hProcess&
	Dim lpBaseAdd&, lpCurAdd&, bRead As Boolean
	Dim dwCurHP&
	
	hKTWindow = FindWindow("_Class", vbNullString)
	If hKTWindow = 0 Then Exit Sub
	GetWindowThreadProcessId hKTWindow, dwProcessId
	hProcess = OpenProcess(PROCESS_VM_READ, False, dwProcessId)
	
	'Get Current HP
	bRead = ReadProcessMemory(hProcess, NPC_BASE_ADD, lpBaseAdd, 4, 0&) '
	If bRead = True Then
		lpCurAdd = lpBaseAdd + NPC_CURLIFE_OFFSET + NPC_DATA_SIZE
		bRead = ReadProcessMemory(hProcess, lpCurAdd, dwCurHP, 4, 0&)
		If bRead = True Then
			MsgBox CStr(dwCurHP)
		Else
			''
		End If
	End If
	Call CloseHandle(hProcess)
	End
End Sub



Cách đọc thông tin máu bằng C#

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace WindowsApplication2
{
	public partial class Form1 : Form
	{
		[DllImport("user32", EntryPoint = "FindWindowA", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
		public static extern int FindWindow(string lpClassName, string lpWindowName);
		[DllImport("user32", EntryPoint = "FindWindowExA", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
		public static extern int FindWindowEx(int hWnd1, int hWnd2, string lpsz1, string lpsz2);		
		[DllImport("user32.dll")]
		public static extern uint GetWindowThreadProcessId(int hWnd, out int lpdwProcessId);
		[DllImport("kernel32.dll")]
		public static extern int OpenProcess(int dwDesiredAccess, bool bInheritHandle, int dwProcessId);

		[DllImport("kernel32.dll")]
		static extern bool ReadProcessMemory(
			IntPtr hProcess,
			IntPtr lpBaseAddress,
			byte[] lpBuffer,
			int dwSize,
			int lpNumberOfBytesWritten
		); 
	

		[DllImport("kernel32.dll")]
		public static extern bool WriteProcessMemory(int hProcess, int lpBaseAddress, byte lpBuffer, int nSize, int lpNumberOfBytesWritten);

		private int PROCESS_VM_OPERATION = 0x8;
		private int PROCESS_VM_READ = 0x10;
		private int PROCESS_VM_WRITE = 0x20;
		private int PROCESS_ALL_ACCESS = 0x1F0FFF;

		private int NPC_BASE_ADD = 0x78AEAC;
		private int NPC_DATA_SIZE = 0xB00C;
		private int NPC_CURLIFE_OFFSET = 0x338;
		private int NPC_NAME_OFFSET = 0xAC6C;

		private int NPC_MAXLIFE_OFFSET = 0x334;

		public Form1()
		{
			InitializeComponent();
		}

		private void Form1_Load(object sender, EventArgs e)
		{
			int hKTWindow, dwProcessId, dwThreatID, hProcess;
			int lpBaseAdd, lpCurAdd;
			bool bRead;
			int dwCurHP, dwMaxHP;
			string szName;
			hKTWindow = FindWindow("_Class", null);
			if (hKTWindow == 0) Application.Exit();
			GetWindowThreadProcessId( hKTWindow,out dwProcessId);
			hProcess = OpenProcess(PROCESS_VM_READ, false, dwProcessId);
			
			byte[] buffer = new byte[4];
			bRead = ReadProcessMemory((IntPtr)hProcess, (IntPtr)NPC_BASE_ADD, buffer, buffer.Length, 0);
			lpBaseAdd = (int)BitConverter.ToUInt32(buffer, 0);
			lpCurAdd = lpBaseAdd + NPC_CURLIFE_OFFSET + NPC_DATA_SIZE;

			bRead = ReadProcessMemory((IntPtr)hProcess, (IntPtr)lpCurAdd, buffer, buffer.Length, 0);
			dwCurHP = (int)BitConverter.ToUInt32(buffer, 0);
			MessageBox.Show(dwCurHP.ToString());
		}
	}
}

Chúc các bạn thành công

Hướng dẫn anh em tiếp phần debug hàm Run đi Thâm ơi, thanks nhiều lắm, cách debug KPlayer Base luôn nhé. Và Cách debug hàm xuất chiêu...
0

#17 User is offline   totogo 

  • Nhóm: Advance Member
  • Bài Viết: 51
  • Gia Nhập: 18-July 06
  • Căn bản tin học tốt
  • Pip

Gửi vào 07 December 2010 - 10:49 AM

Anh có thể hướng dẫn em debug skill được không anh
0

#18 User is offline   Zero123456789 

  • Nhóm: Newbies
  • Bài Viết: 3
  • Gia Nhập: 26-November 07
  • Thành viên mới

Gửi vào 19 December 2010 - 10:20 AM

Chào các anh!
Mình ko phải là dân IT, chỉ hơi ham game online chút (hiện giờ đang cày KT :rolleyes: ), đọc sơ qua bài của bạn Thâm tất nhiên là mình không thể hiểu hết dc, nhưng cho mình hỏi cái file att KT hook đó nhúng vào file game cua KT có tác dụng j ko?
0

#19 User is offline   ZeRo_cold 

  • Nhóm: Member
  • Bài Viết: 15
  • Gia Nhập: 03-March 09
  • Thành viên mới

Gửi vào 28 March 2011 - 04:00 PM

Cám ơn bạn rất nhiều..
bạn có thể cho mình nick chat .. mình trao đổi thêm.
thanks :)

Bài viết này được chỉnh sửa bởi ZeRo_cold: 28 March 2011 - 04:16 PM

0

#20 User is offline   xbao 

  • Nhóm: Newbies
  • Bài Viết: 1
  • Gia Nhập: 08-April 10
  • Thành viên mới

Gửi vào 17 April 2012 - 11:13 AM

Bác thâm hướng dẫn cách debug gởi dữ liệu đi, cụ thể là hàm di chuyển, lấy dữ liệu thì mình làm đc rồi, thanks :)
0

Chia sẻ chủ để


  • 2 Trang +
  • 1
  • 2
  • Bạn không thể gửi chủ đề mới
  • Bạn không thể gửi trả lời cho chủ đề này

1 người đang đọc chủ đề này
0 thành viên, 1 khách, 0 thành viên ẩn