Cơ bản về hooking

Góc lập trình viên

5.0 (1 đánh giá)
Tạo bởi K9 Cập nhật lần cuối 22:25 23-09-2020 3.445 lượt xem 1 bình luận
Học nhanh

Danh sách bài học

Cơ bản về hooking

Dẫn nhập

Khi dạo quanh các diễn dàn về lập trình hay bảo mật. Đôi khi bạn nghe đến từ khóa hook, injection, callback… làm cho đầu óc quay cuồng. Rất mong hiểu rõ về nó, nhưng càng tra cứu google thì càng thấy mông lung hơn.

Vậy Kteam sẽ giúp bạn có cái nhìn rõ ràng hơn về hooking.


Hooking là gì?

Hook tiếng Việt dịch sát nghĩa là móc câu(lưỡi câu).

 

Còn trong lập trình thì hooking là một kỹ thuật mà bạn có thể đọc, ghi hoặc thực thi đoạn code bất kỳ lên một chương trình.

2 kỹ thuật hooking thông dụng sửa code của chương trình đích chèn đoạn code mong muốn của mình vào và tiêm một dll hook chứa callback function vào chương trình đích để gửi và nhận lệnh theo ý.


Inject là gì?

Inject là kỹ thuật tiêm một đoạn code (có thể là cả thư viện) vào một chương trình.


Callback là gì?

Callback là một hàm được truyền vào một hàm thông qua tham số hàm.

Hàm callback này có thể được gọi ở bên trong hàm mà nó được truyền vào. Hàm callback này có thể được lập trình viên định nghĩa từ bên ngoài hàm. (xem thêm về callback qua bài DELEGATE TRONG C#)


Kỹ thuật hooking cơ bản (sửa code chương trình đích)

Một số chương trình đơn giản có thể dịch ngược code thì có thể dung kỹ thuật hooking đó là sửa code của chương trình.

Các chương trình dùng để dịch ngược code thông dụng(tùy vào ngôn ngữ lập trình nên chương trình) như:

  • DnSpy(.Net): 

  • IDA(C++):

  • uncompyle6 (python):

  • AndroChef Java Decompiler(java):

Ví dụ chương trình notepad của window. Bạn có thể sửa code để mỗi khi bạn nhấn new file thì đồng thời notepad sẽ tự động lưu luôn bản text bạn đang biên soạn vào một đường dẫn mặc định thay vì hiện ra một bảng thông báo bạn có muốn lưu hay không.

Vì bản chất là bạn đã sửa code của chương trình nên bạn cũng có thể viết một đoạn code callback mỗi khi có message được gọi tới chương trình đích này. Để từ callback function này bạn có thể đưa vào đoạn code bất kỳ hoặc đọc dữ liệu mong muốn. Đây cũng là tư tưởng của kỹ thuật hook thứ 2.

Ưu điểm:

  • Nhanh gọn lẹ dễ làm với các chương trình có thể địch ngược.

Nhược điểm:

  • Dễ dàng bị phát hiện nếu lập trình viên của chương trình đích có check sum hoặc kiểm tra tính toàn vẹn của file thực thi.
  • Cần biết lập trình để đọc hiểu code rồi mới có thể sửa code chương trình được.
  • Đôi khi chương trình đã bị mã hóa chống dịch ngược gây rất nhiều khó khăn.

Kỹ thuật hooking nâng cao(inject hook dll)

Inject hook dll là kỹ thuật bạn sẽ tiêm một dll đã viết sẵn cấu trúc callback vào chương trình đích.

Như dưới đây là một đoạn code C# định nghĩa hàm inject Dll hook vào chương trình có WindowHandle chứa trong biến WindowHwnd.

// Thủ tục định nghĩa chưa Inject hook
        private bool _isInjected = false;

        // Thủ tục định nghĩa chưa Inject hook
        public bool isInjected
        {
            get { return _isInjected; }
        }

        // Thủ tục Inject hook
        public int Inject()
        {
            var result = HookGame.InjectDll(WindowHwnd);
            if (result == 1)
            {
                _isInjected = true;
                this.HookMsg = HookGame.GetMsg();
            }
            return result;
        }

        // Thủ tục DeInject hook
        public int DeInject()
        {
            var result = HookGame.UnmapDll(WindowHwnd);
            _isInjected = false;
            return result;
        }

Định nghĩa của hàm Inject DeInject được viết trong Dll C++

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;
}

Còn dưới đây là một đoạn code xử lý callback của Dll hook

LRESULT CALLBACK NewWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{

	if (uMsg == WM_HOOK_WRITE)
	{
		switch (wParam)
		{
		case cmd_setParam1:
			input1 = lParam;
			break;
		case cmd_setParam2:
			input2 = lParam;
			break;
		case cmd_setParam3:
			input3 = lParam;
			break;
		case cmd_setParam4:
			input4 = lParam;
			break;
		case cmd_setParam5:
			input5 = lParam;
			break;
		case cmd_setParam6:
			input6 = lParam;
			break;
		case cmd_setParam7:
			input7 = lParam;
			break;
		case cmd_Move:
			//Move(x,y,mode,idmap)
			Move(input1, input2, input3, lParam);
			break;

Tại code C# ta chỉ cần PostMessage đến chính xác biến HookMsg tại WindowHwnd đã được tiêm vào trước đó như ví dụ về hàm di chuyển nhân vật trong game như sau:

// Gửi thông điệp đến cho hook xử lý
        public void MoveTo(int posX, int posY, int mapID)
        {

            WinAPI.PostMessage(WindowHwnd, HookMsg, GameConst.cmd_start, GameConst.FUNC_MOVE_TO);
            WinAPI.PostMessage(WindowHwnd, HookMsg, GameConst.cmd_push, posX);
            WinAPI.PostMessage(WindowHwnd, HookMsg, GameConst.cmd_push, posY);
            WinAPI.PostMessage(WindowHwnd, HookMsg, GameConst.cmd_push, mapID);
            WinAPI.PostMessage(WindowHwnd, HookMsg, GameConst.cmd_end, 0);
        }

PostMessage là một hàm được hỗ trợ sẵn trong thư viện winapi của window.


Thông qua các ví dụ trên ta dễ dàng hình dung ra luồng đi của kỹ thuật hook inject này là:

  • Cần có một hook dll có các phương thức inject, deinject và callback để nhận lệnh từ bên ngoài vào thực thi tương ứng.
  • Tiếp đến cần thực thi inject dll hook này vào chương trình đích
  • Sau đó cần thực thi lệnh nào thì gọi PostMessage vào HookMsg(thay mặt cho hook dll đã inject) để callback function thực hiện nhiệm vụ của mình là thực thi các hàm định nghĩa sẵn ở dll hoặc một function khác do bạn đưa vào.

Vậy là bạn đã có thể bắt một chương trình khác thực hiện mệnh lệnh của mình thông qua kỹ thuật hook này.


Kết

Trên đây là một chút hiểu biết của Kteam về kỹ thuật hooking injection được thể hiện qua ngôn ngữ lập trình C#C++ sẽ giúp bạn có cái nhìn rõ ràng hơn về kỹ thuật thú vị này. Để có thể hiểu sâu hơn về ứng dụng của kỹ thuật bạn hãy tìm kiếm về từ khóa hook hoặc cheat tại website Howkteam.com nhé

Cảm ơn các bạn đã theo dõi bài viết. Hãy để lại bình luận hoặc góp ý của mình để phát triển bài viết tốt hơn. Đừng quên “Luyện tập – Thử thách – Không ngại khó”.


Thảo luận

Nếu bạn có bất kỳ khó khăn hay thắc mắc gì về khóa học, đừng ngần ngại đặt câu hỏi trong phần BÌNH LUẬN bên dưới hoặc trong mục HỎI & ĐÁP trên thư viện Howkteam.com để nhận được sự hỗ trợ từ cộng đồng.

Nội dung bài viết

Tác giả/Dịch giả

K9

Nhà sáng lập Howkteam.com & tác giả các khóa học C#, Auto, Unity3D, Python....

Với mong muốn mang đến kiến thức chất lượng, miễn phí cho mọi người, với tâm huyết phá bỏ rào cản kiến thức từ việc giáo dục thu phí. Tôi đã cùng đội ngũ Kteam đã lập nên trang website này để thế giới phẳng hơn.
Hãy cùng chúng tôi lan tỏa kiến thức đến cộng đồng! 

Khóa học

Góc lập trình viên

Coder corner - Nơi lưu trữ những tâm tư của các coder vỡ lòng đến cạn lòng

Đánh giá

letuananhlqd đã đánh giá 16:07 28-09-2020

Bình luận

Để bình luận, bạn cần đăng nhập bằng tài khoản Howkteam.

Đăng nhập
teafilm2020 đã bình luận 09:17 24-09-2020

Thanks anh Kim Long, đọc bài này thấy sáng ra nhiều idea.

Không có video.