Bài viết mô tả việc dùng Detours
Bài viết này không đi sâu chi tiết vào Detours, chỉ mô tả cách sử dụng Detours trong trường hợp ko dùng được CheatEngine. Cách thực hiện này có thể áp dụng trong các trường hợp có logic tương tự.
Do mấy bữa nay bận nên không thể ngồi dò base address của lua_State nên không sửa hoàn chỉnh cái auto Tru Tiên. Hôm nay cuối tuần mình sẽ ngồi viết tutorial cho phần này. Sau này nếu có ai muốn tìm giá trị của lua_State hay những địa chỉ trong trường hợp tương tự thì vẫn biết đường mà mò.
d.html . Bản mới nhất hiện tại là 5.1.4, có thể dùng bản này hoặc 5.1.1. Sau khi download về và extract trong 1 folder Lua-5.1.1. Sau đó tạo một project static library Lua-5.1.1.vcproj, add các files trong thư mục src (nhớ bỏ 2 file lua.c và luac.c là 2 files build lua command line) vào project.
Mục đích là build static library Lua. Có thể tạo solution riêng để build lua library 1 lần thôi.
Software package for re-routing Win32 APIs underneath applications. Under commercial release for over 10 years, Detours is licensed by over 100 ISVs and used within nearly every product team at Microsoft.để thực hiện API hooking, cụ thể là ReAlloc nhằm lấy được base address của lua_State dùng cho AutoPlay. Lý do để thực hiện việc này là không thể dò lua_State bằng cách thông thường dùng CheatEngine (xem lại bài ).
Bài viết này không đi sâu chi tiết vào Detours, chỉ mô tả cách sử dụng Detours trong trường hợp ko dùng được CheatEngine. Cách thực hiện này có thể áp dụng trong các trường hợp có logic tương tự.
Do mấy bữa nay bận nên không thể ngồi dò base address của lua_State nên không sửa hoàn chỉnh cái auto Tru Tiên. Hôm nay cuối tuần mình sẽ ngồi viết tutorial cho phần này. Sau này nếu có ai muốn tìm giá trị của lua_State hay những địa chỉ trong trường hợp tương tự thì vẫn biết đường mà mò.
Build Lua library
Đầu tiên mình check phiên bản Lua mà game đang sử dụng (là 5.1.1), sau đó phải kiếm 1 bản lua về tại http://www.lua.org/downloaMục đích là build static library Lua. Có thể tạo solution riêng để build lua library 1 lần thôi.
Sau khi build xong có lua-5.1.1d.lib và lua-5.1.1.lib, có thể copy lên thư mục Lib để dễ reference.
Cách thức cấp phát lua_State
Tạo một project đơn giản dạng Win32 application (dùng cái này khỏi dính dáng đến MFC) để biết lua_State được cấp phát như thế nào. Tạo Win32 application viết dạng Dialog1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 | // Test.cpp : Defines the entry point for the application. #include "stdafx.h" // Header for Lua library extern "C" { #include "../Lib/Lua-5.1.1/src/lua.h" #include "../Lib/Lua-5.1.1/src/lauxlib.h" #include "../Lib/Lua-5.1.1/src/lualib.h" }; // 21/Nov/2009 fixed link to Lua library #if defined(_DEBUG) // Debug libraries #pragma comment(lib, "../Lib/lua-5.1.1d.lib") #else // Release libraries #pragma comment(lib, "../Lib/lua-5.1.1.lib") #endif HINSTANCE g_hInstance = NULL; BOOL CALLBACK DialogProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); int APIENTRY WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { // TODO: Place code here. g_hInstance = hInstance; HWND hDialog = 0; hDialog = ::CreateDialog(hInstance, MAKEINTRESOURCE(IDD_TEST_DLG), 0, DialogProc); if (!hDialog) { LPVOID lpBuffer; ::FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError(), 0, ( LPTSTR )&lpBuffer, 0, NULL); ::MessageBox(NULL, ( LPTSTR )lpBuffer, _T( "CreateDialog" ), MB_ICONEXCLAMATION | MB_OK); ::LocalFree(lpBuffer); return 1; } else { ::ShowWindow(hDialog, nCmdShow); } MSG msg; int status; while ((status = ::GetMessage(&msg, 0, 0, 0)) != 0) { if (status == -1) { return -1; } if (!::IsDialogMessage(hDialog, & msg)) { ::TranslateMessage( & msg ); ::DispatchMessage( & msg ); } } return msg.wParam; } BOOL CALLBACK DialogProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { WORD wId, wEvent; HICON hIcon = NULL; lua_State* state = NULL; TCHAR buffer[1024] = { '\0' }; switch (message) { case WM_INITDIALOG: hIcon = ::LoadIcon(g_hInstance, MAKEINTRESOURCE(IDI_ICON)); if (hIcon) { ::SendMessage(hWnd, WM_SETICON, ( WPARAM )ICON_SMALL, ( LPARAM )hIcon); } return TRUE; case WM_COMMAND: wId = LOWORD(wParam); wEvent = HIWORD(wParam); // Parse the menu selections: switch (wId) { case IDC_BUTTON_TEST: state = luaL_newstate(); wsprintf(buffer, _T( "[Process %p] " ), ::GetCurrentProcessId(), state); ::MessageBox(NULL, buffer, _T( "Test" ), MB_OK); if (state != NULL) { lua_close(state); } break ; case IDOK: ::DestroyWindow(hWnd); break ; case IDCANCEL: ::DestroyWindow(hWnd); break ; default : return ::DefWindowProc(hWnd, message, wParam, lParam); } return TRUE; case WM_DESTROY: ::PostQuitMessage(0); return TRUE; case WM_CLOSE: ::DestroyWindow(hWnd); return TRUE; } return FALSE; } |
Test project đơn giản chỉ là một dialog có một nút test.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | // Header for Lua library extern "C" { #include "../Lib/Lua-5.1.1/src/lua.h" #include "../Lib/Lua-5.1.1/src/lauxlib.h" #include "../Lib/Lua-5.1.1/src/lualib.h" }; // 21/Nov/2009 fixed link to Lua library #if defined(_DEBUG) // Debug libraries #pragma comment(lib, "../Lib/lua-5.1.1d.lib") #else // Release libraries #pragma comment(lib, "../Lib/lua-5.1.1.lib") #endif |
Khi thực hiện nhấn button Test sẽ tạo một lua_State, do đó để break point ngay đây xem có được thông tin gì không. Mình biết lua_State được tạo bởi luaL_newstate.
1 2 3 4 5 | // Parse the menu selections: switch (wId) { case IDC_BUTTON_TEST: state = luaL_newstate(); |
Thực hiện F11 step into sẽ vào lua_newstate xem tiếp
1 2 3 4 5 | LUALIB_API lua_State *luaL_newstate ( void ) { lua_State *L = lua_newstate(l_alloc, NULL); if (L) lua_atpanic(L, &panic); return L; } |
Tiếp tục step into lua_newstate với l_alloc
1 2 3 4 5 6 | LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) { int i; lua_State *L; global_State *g; void *l = (*f)(ud, NULL, 0, state_size(LG)); if (l == NULL) return NULL; |
1 2 3 4 5 6 7 8 9 10 | static void *l_alloc ( void *ud, void *ptr, size_t osize, size_t nsize) { ( void )ud; ( void )osize; if (nsize == 0) { free (ptr); return NULL; } else return realloc (ptr, nsize); } |
Tới đây mình hầu như đã có thông tin mong muốn
- Lua alloc sử dụng API realloc
- Kích thước cấp phát là nzine
Có nghĩa là lua_State là giá trị trả về của realloc với size là 376. Con số này rất quan trọng mình sẽ ghi nhớ.