├── .gitignore ├── Chapter10_ResponsiveHacks ├── Chapter10_ResponsiveHacks.vcxproj └── main-responsiveHacks.cpp ├── Chapter11_SearchAlgorithms ├── Chapter11_SearchAlgorithms.cpp ├── Chapter11_SearchAlgorithms.vcxproj ├── Chapter11_SearchAlgorithms.vcxproj.filters ├── DummyWindow.cpp ├── DummyWindow.h └── WindowCode.h ├── Chapter11_StateMachines ├── Chapter11_StateMachines.cpp ├── Chapter11_StateMachines.vcxproj ├── Chapter11_StateMachines.vcxproj.filters └── Game.h ├── Chapter1_BasicMemory ├── Chapter1_BasicMemory.vcxproj ├── Chapter1_BasicMemory.vcxproj.filters ├── Location-BasicMem.h └── game-BasicMem.cpp ├── Chapter1_MemoryPointers ├── Chapter1_MemoryPointers.vcxproj ├── Chapter2_MemoryPointers.filters ├── Location-MemPointer.h └── game-MemPointer.cpp ├── Chapter2_BasicDebugging ├── Chapter2_BasicDebugging.filters ├── Chapter2_BasicDebugging.vcxproj ├── Location-BasicDebugging.h └── game-BasicDebugging.cpp ├── Chapter3_CloseMutex ├── Chapter3_CloseMutex.filters ├── Chapter3_CloseMutex.vcxproj ├── Location-CloseMutex.h └── game-CloseMutex.cpp ├── Chapter3_FindingFiles ├── Chapter3_FindingFiles.filters ├── Chapter3_FindingFiles.vcxproj ├── Location-FindingFiles.h └── game-FindingFiles.cpp ├── Chapter4_CodeToMemory ├── Chapter4_CodeToMemory.filters ├── Chapter4_CodeToMemory.vcxproj └── main-codeToMemory.cpp ├── Chapter5_AdvancedMemoryForensics_Scanning ├── Chapter5_AdvancedMemoryForensics_Scanning.vcxproj └── main-advancedMemoryForensics-Scanning.cpp ├── Chapter6_AccessingMemory ├── Chapter6_AccessingMemory.vcxproj └── main-accessingMemory.cpp ├── Chapter7_CodeInjection ├── Chapter7_CodeInjection.vcxproj └── main-codeInjection.cpp ├── Chapter7_CodeInjection_DLL ├── Chapter7_CodeInjection_DLL.vcxproj ├── Chapter7_CodeInjection_DLL.vcxproj.filters └── dllmain.cpp ├── Chapter8_AdobeAirHook ├── AdobeAirHook.cpp ├── AdobeAirHook.h ├── AdobeAirHook.vcxproj ├── AdobeAirHook.vcxproj.filters ├── AdobeAirHookCallbacks.h ├── DebugConsole.cpp ├── DebugConsole.h ├── ExecutableModule.cpp ├── ExecutableModule.h ├── ThreadLock.h └── dllmain.cpp ├── Chapter8_ControlFlow ├── CallHookExample.cpp ├── Chapter8_ControlFlow.vcxproj ├── Chapter8_ControlFlow.vcxproj.filters ├── IATHookExample.cpp ├── NOPExample.cpp ├── VFHookExample.cpp ├── main-controlFlow.cpp └── main.h ├── Chapter8_Direct3DApplication ├── Chapter8_Direct3DApplication.vcxproj ├── Chapter8_Direct3DApplication.vcxproj.filters └── main.cpp ├── Chapter8_Direct3DHook ├── Chapter8_Direct3DHook.vcxproj ├── Chapter8_Direct3DHook.vcxproj.filters ├── DirectXHook.cpp ├── DirectXHook.h ├── DirectXHookCallbacks.h ├── main.cpp └── memory.h ├── GameHackingExamples.sln ├── LICENSE ├── LuaScripts ├── Chapter1_SearchingForAssemblyPatterns.lua ├── Chapter1_SearchingForStrings.lua ├── Chapter5_CountLinkedListNodes.lua ├── Chapter5_VerifyLinkedList.lua └── Chapter5_VerifyMap.lua ├── README.md ├── allegro_linkers.h ├── arial.ttf ├── bin ├── Chapter10_ResponsiveHacks.exe ├── Chapter11_SearchAlgorithms.exe ├── Chapter11_StateMachines.exe ├── Chapter1_BasicMemory.exe ├── Chapter1_MemoryPointers.exe ├── Chapter2_BasicDebugging.exe ├── Chapter3_CloseMutex.exe ├── Chapter3_FindingFiles.exe ├── Chapter4_CodeToMemory.exe ├── Chapter5_AdvancedMemoryForensics_Scanning.exe ├── Chapter6_AccessingMemory.exe ├── Chapter7_CodeInjection.exe ├── Chapter8_ControlFlow.exe ├── Chapter8_Direct3DApplication.exe └── DEBUG_BUILDS │ ├── Chapter10_ResponsiveHacks.exe │ ├── Chapter10_ResponsiveHacks.ilk │ ├── Chapter10_ResponsiveHacks.pdb │ ├── Chapter11_SearchAlgorithms.exe │ ├── Chapter11_SearchAlgorithms.ilk │ ├── Chapter11_SearchAlgorithms.pdb │ ├── Chapter11_StateMachines.exe │ ├── Chapter11_StateMachines.ilk │ ├── Chapter11_StateMachines.pdb │ ├── Chapter1_BasicMemory.exe │ ├── Chapter1_BasicMemory.ilk │ ├── Chapter1_BasicMemory.pdb │ ├── Chapter1_MemoryPointers.exe │ ├── Chapter1_MemoryPointers.ilk │ ├── Chapter1_MemoryPointers.pdb │ ├── Chapter2_BasicDebugging.exe │ ├── Chapter2_BasicDebugging.ilk │ ├── Chapter2_BasicDebugging.pdb │ ├── Chapter3_CloseMutex.exe │ ├── Chapter3_CloseMutex.ilk │ ├── Chapter3_CloseMutex.pdb │ ├── Chapter3_FindingFiles.exe │ ├── Chapter3_FindingFiles.ilk │ ├── Chapter3_FindingFiles.pdb │ ├── Chapter4_CodeToMemory.exe │ ├── Chapter4_CodeToMemory.ilk │ ├── Chapter4_CodeToMemory.pdb │ ├── Chapter5_AdvancedMemoryForensics_Scanning.exe │ ├── Chapter5_AdvancedMemoryForensics_Scanning.ilk │ ├── Chapter5_AdvancedMemoryForensics_Scanning.pdb │ ├── Chapter6_AccessingMemory.exe │ ├── Chapter6_AccessingMemory.ilk │ ├── Chapter6_AccessingMemory.pdb │ ├── Chapter7_CodeInjection.exe │ ├── Chapter7_CodeInjection.ilk │ ├── Chapter7_CodeInjection.pdb │ ├── Chapter7_CodeInjection_DLL.ilk │ ├── Chapter7_CodeInjection_DLL.pdb │ ├── Chapter8_AdobeAirHook.ilk │ ├── Chapter8_AdobeAirHook.pdb │ ├── Chapter8_ControlFlow.exe │ ├── Chapter8_ControlFlow.ilk │ ├── Chapter8_ControlFlow.pdb │ ├── Chapter8_Direct3DApplication.exe │ ├── Chapter8_Direct3DApplication.ilk │ ├── Chapter8_Direct3DApplication.pdb │ ├── Chapter8_Direct3DHook.ilk │ └── Chapter8_Direct3DHook.pdb └── game.map /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files 2 | *.slo 3 | *.lo 4 | *.o 5 | *.obj 6 | 7 | # Precompiled Headers 8 | *.gch 9 | *.pch 10 | 11 | # Compiled Dynamic libraries 12 | *.so 13 | *.dylib 14 | *.dll 15 | 16 | # Fortran module files 17 | *.mod 18 | 19 | # Compiled Static libraries 20 | *.lai 21 | *.la 22 | *.a 23 | *.lib 24 | 25 | # Executables 26 | *.exe 27 | *.out 28 | *.app 29 | 30 | 31 | # VS stuff 32 | *.suo 33 | *.sdf 34 | *.user 35 | 36 | #other directories 37 | */ipch/* 38 | */Debug/* 39 | */Release/* 40 | */BuildTemp/* 41 | ipch/* 42 | Debug/* 43 | Release/* 44 | BuildTemp/* 45 | -------------------------------------------------------------------------------- /Chapter10_ResponsiveHacks/Chapter10_ResponsiveHacks.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {E28E3DC6-2614-43B9-83E4-86D6F9A585B1} 15 | Win32Proj 16 | Chapter10_ResponsiveHacks 17 | Chapter10_ResponsiveHacks 18 | 19 | 20 | 21 | Application 22 | true 23 | Unicode 24 | 25 | 26 | Application 27 | false 28 | true 29 | Unicode 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | true 43 | $(SolutionDir)\BuildTemp\$(ProjectName)_$(Configuration)\ 44 | $(SolutionDir)\bin\DEBUG_BUILDS\ 45 | 46 | 47 | false 48 | $(SolutionDir)\BuildTemp\$(ProjectName)_$(Configuration)\ 49 | $(SolutionDir)\bin\ 50 | 51 | 52 | 53 | 54 | 55 | Level3 56 | Disabled 57 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 58 | 4Bytes 59 | 60 | 61 | Console 62 | true 63 | false 64 | 65 | 66 | 67 | 68 | Level3 69 | 70 | 71 | Disabled 72 | true 73 | true 74 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 75 | 4Bytes 76 | 77 | 78 | Console 79 | true 80 | true 81 | true 82 | 83 | 84 | false 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | -------------------------------------------------------------------------------- /Chapter10_ResponsiveHacks/main-responsiveHacks.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | // WARNING: if this code is killed mid-execute or you switch to another window (not the console) 6 | // while it's executing, it may cause the system to think a modifier key is stuck. 7 | // If this happens, you can tap shift, ctrl, and alt on the LEFT side of your keyboard to "unstick it" 8 | 9 | 10 | 11 | 12 | 13 | // SendInput() example code 14 | void sendKeyWithSendInput(WORD key, bool up) 15 | { 16 | INPUT input = {0}; 17 | input.type = INPUT_KEYBOARD; 18 | input.ki.wVk = key; 19 | input.ki.dwFlags = 0; 20 | 21 | if (up) 22 | input.ki.dwFlags |= KEYEVENTF_KEYUP; 23 | SendInput(1, &input, sizeof(input)); 24 | } 25 | 26 | void sendModifiersWithSendInput(DWORD flags, bool up) 27 | { 28 | if (flags & 1) 29 | sendKeyWithSendInput(VK_LSHIFT, up); 30 | if (flags & 2) 31 | sendKeyWithSendInput(VK_LCONTROL, up); 32 | if (flags & 4) 33 | sendKeyWithSendInput(VK_LMENU, up); 34 | } 35 | 36 | void sendCharWithSendInput(char letter) 37 | { 38 | SHORT keyFlags = VkKeyScanA(letter); 39 | 40 | WORD key = keyFlags & 0xFF; 41 | DWORD flags = (keyFlags >> 8) & 0xFF; 42 | 43 | sendModifiersWithSendInput(flags, false); 44 | 45 | sendKeyWithSendInput(key, false); 46 | sendKeyWithSendInput(key, true); 47 | 48 | sendModifiersWithSendInput(flags, true); 49 | } 50 | 51 | void typeStringWithSendInput(const char* string) 52 | { 53 | for (int i = 0; i < strlen(string); i++) 54 | { 55 | sendCharWithSendInput(string[i]); 56 | Sleep(80); 57 | } 58 | } 59 | 60 | // SendMessage example code 61 | void sendKeyWithSendMessage(HWND window, WORD key, char letter) 62 | { 63 | SendMessageA(window, WM_KEYDOWN, key, 0); 64 | if (letter != 0) 65 | SendMessageA(window, WM_CHAR, letter, 1); 66 | SendMessageA(window, WM_KEYUP, key, 1); 67 | } 68 | 69 | 70 | void sendCharWithSendMessage(HWND window, char letter) 71 | { 72 | SHORT keyFlags = VkKeyScanA(letter); 73 | 74 | WORD key = keyFlags & 0xFF; 75 | DWORD flags = (keyFlags >> 8) & 0xFF; 76 | 77 | sendKeyWithSendMessage(window, key, letter); 78 | } 79 | 80 | void typeStringWithSendMessage(HWND window, const char* string) 81 | { 82 | for (int i = 0; i < strlen(string); i++) 83 | { 84 | sendCharWithSendMessage(window, string[i]); 85 | Sleep(80); 86 | } 87 | } 88 | 89 | 90 | 91 | 92 | DWORD WINAPI exampleThread(LPVOID lpParam) 93 | { 94 | Sleep(500); 95 | typeStringWithSendInput("Typing using SendInput()!\rHow does it look? :)\r\r"); 96 | 97 | auto window = FindWindowA(NULL, "Chapter10 Input Example"); 98 | typeStringWithSendMessage(window, "Typing using SendMessage()!\rEffectively the same, but more powerful :-)\r\r"); 99 | 100 | std::cout << std::endl << std::endl << "DONE! you can close this now!" << std::endl; 101 | 102 | return 0; 103 | } 104 | 105 | 106 | int main(void) 107 | { 108 | std::cout << "WARNING: Don't switch between windows until this application is done typing" << std::endl; 109 | system("pause"); 110 | std::cout << "Everything below here is being programmatically typed using the keyboard" << std::endl << std::endl; 111 | 112 | SetConsoleTitleA("Chapter10 Input Example"); 113 | 114 | CreateThread(NULL, 0, exampleThread, 0, 0, NULL); 115 | 116 | char temp; 117 | while (true) { 118 | std::cin >> temp; 119 | } 120 | } -------------------------------------------------------------------------------- /Chapter11_SearchAlgorithms/Chapter11_SearchAlgorithms.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include "WindowCode.h" 9 | 10 | 11 | #define TILE_COST 1 12 | 13 | class AStarNode; 14 | typedef std::shared_ptr AStarNodePtr; 15 | 16 | class AStarNode 17 | { 18 | public: 19 | int x, y; 20 | int g, score; 21 | AStarNodePtr parent; 22 | 23 | AStarNode(int x, int y, int cost, AStarNodePtr p, int score = 0) 24 | : x(x), y(y), g(cost), score(score), parent(p) 25 | {} 26 | static AStarNodePtr makePtr(int x, int y, int cost, AStarNodePtr p, int score = 0) 27 | { 28 | return AStarNodePtr(new AStarNode(x, y, cost, p, score)); 29 | } 30 | int heuristic(const int destx, int desty) const 31 | { 32 | int xd = destx - x; 33 | int yd = desty - y; 34 | return abs(xd) + abs(yd); 35 | } 36 | void updateScore(int endx, int endy) 37 | { 38 | auto h = this->heuristic(endx, endy) * TILE_COST; 39 | this->score = g + h; 40 | } 41 | AStarNodePtr getCopy() 42 | { 43 | return AStarNode::makePtr(x, y, g, parent, score); 44 | } 45 | std::vector getChildren(int width, int height) 46 | { 47 | std::vector ret; 48 | auto copy = getCopy(); 49 | if (x > 0) 50 | ret.push_back(AStarNode::makePtr(x - 1, y, g + TILE_COST, copy)); 51 | if (y > 0) 52 | ret.push_back(AStarNode::makePtr(x, y - 1, g + TILE_COST, copy)); 53 | if (x < width - 1) 54 | ret.push_back(AStarNode::makePtr(x + 1, y, g + TILE_COST, copy)); 55 | if (y < height - 1) 56 | ret.push_back(AStarNode::makePtr(x, y + 1, g + TILE_COST, copy)); 57 | return ret; 58 | } 59 | }; 60 | 61 | bool operator<(const AStarNodePtr &a, const AStarNodePtr &b) 62 | { 63 | return a->score > b->score; 64 | } 65 | bool operator==(const AStarNodePtr &a, const AStarNodePtr &b) 66 | { 67 | return a->x == b->x && a->y == b->y; 68 | } 69 | 70 | template 71 | void makeList(AStarNodePtr end, std::vector nodes, int path[WIDTH][HEIGHT]) 72 | { 73 | for (auto n = nodes.begin(); n != nodes.end(); n++) 74 | path[(*n)->x][(*n)->y] = 2; 75 | 76 | AStarNodePtr node = end; 77 | while (node.get() != nullptr) 78 | { 79 | path[node->x][node->y] = 1; 80 | node = node->parent; 81 | } 82 | } 83 | 84 | template 85 | bool doAStarSearch( 86 | int map[WIDTH][HEIGHT], 87 | int startx, int starty, 88 | int endx, int endy, 89 | int path[WIDTH][HEIGHT]) 90 | { 91 | std::priority_queue frontier; 92 | std::vector allNodes; 93 | 94 | auto node = AStarNode::makePtr(startx, starty, 0, nullptr); 95 | node->updateScore(endx, endy); 96 | allNodes.push_back(node); 97 | 98 | while (true) 99 | { 100 | if (node->x == endx && node->y == endy) 101 | { 102 | makeList(node, allNodes, path); 103 | return true; 104 | } 105 | 106 | auto children = node->getChildren(WIDTH, HEIGHT); 107 | for (auto c = children.begin(); c != children.end(); c++) 108 | { 109 | if (map[(*c)->x][(*c)->y] == BLOCKING) 110 | continue; 111 | auto found = std::find(allNodes.rbegin(), allNodes.rend(), *c); 112 | if (found != allNodes.rend()) 113 | { 114 | if (*found > *c) 115 | { 116 | (*found)->g = (*c)->g; 117 | (*found)->parent = (*c)->parent; 118 | (*found)->updateScore(endx, endy); 119 | } 120 | } 121 | else 122 | { 123 | (*c)->updateScore(endx, endy); 124 | frontier.push(*c); 125 | allNodes.push_back(*c); 126 | } 127 | } 128 | 129 | if (frontier.size() == 0) 130 | return false; 131 | 132 | node = frontier.top(); 133 | frontier.pop(); 134 | } 135 | } 136 | 137 | 138 | 139 | int main (int argc, char *argv[]) 140 | { 141 | searchFunction = doAStarSearch; 142 | showWindow(); 143 | return 0; 144 | } -------------------------------------------------------------------------------- /Chapter11_SearchAlgorithms/Chapter11_SearchAlgorithms.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {35470A34-CBB0-41D1-A54B-E1CF3DE9A3B7} 15 | Chapter11_SearchAlgorithms 16 | 17 | 18 | 19 | Application 20 | true 21 | Unicode 22 | $(SolutionDir)\BuildTemp\$(ProjectName)_$(Configuration)\ 23 | $(SolutionDir)\bin\DEBUG_BUILDS\ 24 | 25 | 26 | Application 27 | false 28 | true 29 | Unicode 30 | $(SolutionDir)\BuildTemp\$(ProjectName)_$(Configuration)\ 31 | $(SolutionDir)\bin\ 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | Level3 47 | Disabled 48 | 49 | 50 | true 51 | 52 | 53 | 54 | 55 | Level3 56 | MaxSpeed 57 | true 58 | true 59 | 60 | 61 | true 62 | true 63 | true 64 | Console 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /Chapter11_SearchAlgorithms/Chapter11_SearchAlgorithms.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | Source Files 23 | 24 | 25 | 26 | 27 | Header Files 28 | 29 | 30 | Header Files 31 | 32 | 33 | -------------------------------------------------------------------------------- /Chapter11_SearchAlgorithms/DummyWindow.cpp: -------------------------------------------------------------------------------- 1 | #include "DummyWindow.h" 2 | 3 | /* 4 | THIS CODE EXISTS ONLY TO DISPLAY A WINDOW, 5 | AND IS NOT RELEVANT TO THE EXAMPLE CODE 6 | */ 7 | 8 | std::map DummyWindow::windowMap; 9 | 10 | DummyWindow::DummyWindow(HINSTANCE _instance) : windowHandle(NULL), instance(_instance) 11 | {} 12 | 13 | DummyWindow::~DummyWindow(void) 14 | { 15 | DummyWindow::unregisterWindow(this, this->windowHandle); 16 | } 17 | 18 | bool DummyWindow::initialize() 19 | { 20 | WNDCLASSEX wcex; 21 | wcex.cbSize = sizeof(WNDCLASSEX); 22 | wcex.style = CS_HREDRAW | CS_VREDRAW; 23 | wcex.lpfnWndProc = WndProc; 24 | wcex.cbClsExtra = 0; 25 | wcex.cbWndExtra = 0; 26 | wcex.hInstance = this->instance; 27 | wcex.hIcon = NULL; //LoadIcon(this->instance, MAKEINTRESOURCE(IDI_APPLICATION)); 28 | wcex.hCursor = LoadCursor(NULL, IDC_ARROW); 29 | wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); 30 | wcex.lpszMenuName = NULL; 31 | wcex.lpszClassName = L"gamhakwind"; 32 | wcex.hIconSm = NULL; //LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_APPLICATION)); 33 | 34 | if (!RegisterClassEx(&wcex)) 35 | { 36 | auto err = GetLastError(); 37 | return false; 38 | } 39 | 40 | this->windowHandle = CreateWindowA 41 | ( 42 | "gamhakwind", 43 | "Game Hacking - Chapter 11 - SearchAlgorithms", 44 | WS_OVERLAPPEDWINDOW, 45 | CW_USEDEFAULT, CW_USEDEFAULT, 46 | 420, 490, 47 | NULL, 48 | NULL, 49 | this->instance, 50 | NULL 51 | ); 52 | if (this->windowHandle == NULL) 53 | { 54 | auto err = GetLastError(); 55 | //return false; 56 | } 57 | 58 | DummyWindow::registerWindow(this, this->windowHandle); 59 | 60 | SetTimer(this->windowHandle, NULL, 50, NULL); 61 | 62 | ShowWindow(this->windowHandle, SW_SHOW); 63 | UpdateWindow(this->windowHandle); 64 | return true; 65 | } 66 | 67 | void DummyWindow::finalize() 68 | { 69 | this->callbackMap.clear(); 70 | } 71 | 72 | int32_t DummyWindow::doMessageLoop() 73 | { 74 | MSG msg; 75 | while (GetMessage(&msg, NULL, 0, 0)) 76 | { 77 | TranslateMessage(&msg); 78 | DispatchMessage(&msg); 79 | } 80 | return static_cast(msg.wParam); 81 | } 82 | 83 | void DummyWindow::setMessageHandler(UINT message, windowMessageCallbackType callback) 84 | { 85 | this->callbackMap[message] = callback; 86 | } 87 | 88 | LRESULT DummyWindow::onMessageReceived(HWND window, UINT message, WPARAM wparam, LPARAM lparam) 89 | { 90 | auto found = this->callbackMap.find(message); 91 | if (found != this->callbackMap.end()) 92 | return found->second(this, message, wparam, lparam); 93 | return DefWindowProc(window, message, wparam, lparam); 94 | } 95 | 96 | void DummyWindow::registerWindow(DummyWindow* dummy, HWND window) 97 | { 98 | DummyWindow::windowMap[window] = dummy; 99 | } 100 | void DummyWindow::unregisterWindow(DummyWindow* dummy, HWND window) 101 | { 102 | auto found = DummyWindow::windowMap.find(window); 103 | if (found != DummyWindow::windowMap.end()) 104 | DummyWindow::windowMap.erase(found); 105 | } 106 | DummyWindow* DummyWindow::findWindow(HWND window) 107 | { 108 | auto found = DummyWindow::windowMap.find(window); 109 | if (found != DummyWindow::windowMap.end()) 110 | return found->second; 111 | return nullptr; 112 | } 113 | 114 | LRESULT DummyWindow::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) 115 | { 116 | auto dummy = DummyWindow::findWindow(hWnd); 117 | if (dummy) 118 | return dummy->onMessageReceived(hWnd, uMsg, wParam, lParam); 119 | return DefWindowProc(hWnd, uMsg, wParam, lParam); 120 | } -------------------------------------------------------------------------------- /Chapter11_SearchAlgorithms/DummyWindow.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | /* 4 | THIS CODE EXISTS ONLY TO DISPLAY A WINDOW, 5 | AND IS NOT RELEVANT TO THE EXAMPLE CODE 6 | */ 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | class DummyWindow; 15 | typedef std::function windowMessageCallbackType; 16 | 17 | class DummyWindow 18 | { 19 | public: 20 | DummyWindow(HINSTANCE _instance); 21 | ~DummyWindow(void); 22 | 23 | bool initialize(); 24 | void finalize(); 25 | int32_t doMessageLoop(); 26 | void setMessageHandler(UINT message, windowMessageCallbackType callback); 27 | 28 | HWND getHandle() { return this->windowHandle; } 29 | 30 | private: 31 | static std::map windowMap; 32 | 33 | static void registerWindow(DummyWindow* dummy, HWND window); 34 | static void unregisterWindow(DummyWindow* dummy, HWND window); 35 | static DummyWindow* findWindow(HWND window); 36 | static LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam); 37 | 38 | 39 | private: 40 | std::map callbackMap; 41 | HWND windowHandle; 42 | HINSTANCE instance; 43 | 44 | LRESULT onMessageReceived(HWND window, UINT message, WPARAM wparam, LPARAM lparam); 45 | }; 46 | 47 | -------------------------------------------------------------------------------- /Chapter11_StateMachines/Chapter11_StateMachines.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "Game.h" 10 | 11 | 12 | // this our our state definition 13 | class StateDefinition 14 | { 15 | public: 16 | StateDefinition(){} 17 | ~StateDefinition(){} 18 | std::function condition; 19 | std::function reach; 20 | }; 21 | 22 | // set up the state machine 23 | std::vector buildMachine() 24 | { 25 | // build a machine with 10 state definitions 26 | std::vector stateMachine(2); 27 | 28 | // get the current definition 29 | auto curDef = stateMachine.begin(); 30 | 31 | // add a state for strong healing 32 | curDef->condition = [](GameSensors* sensors) -> bool { 33 | static float healAt = 50; 34 | if (sensors->detectedStrongHeal()) 35 | { 36 | if (sensors->getStrongHealMaxed()) 37 | { 38 | healAt -= 1; 39 | } 40 | else 41 | { 42 | auto newHealAt = 100 - sensors->getStrongHealIncrease(); 43 | healAt = (healAt + newHealAt) / 2.00f; 44 | } 45 | sensors->clearStrongHealInfo(); 46 | } 47 | return sensors->getHealthPercent() > healAt; 48 | }; 49 | curDef->reach = [](GameSensors* sensors, GameActuators* actuators) { 50 | actuators->strongHeal(); 51 | }; 52 | curDef++; 53 | 54 | // add a state for weak healing 55 | curDef->condition = [](GameSensors* sensors) -> bool { 56 | static float healAt = 70; 57 | static bool hasLearned = false; 58 | if (!hasLearned && sensors->detectedWeakHeal()) 59 | { 60 | hasLearned = true; 61 | healAt = 100 - sensors->getWeakHealIncrease(); 62 | } 63 | return sensors->getHealthPercent() > healAt; 64 | }; 65 | curDef->reach = [](GameSensors* sensors, GameActuators* actuators) { 66 | actuators->weakHeal(); 67 | }; 68 | curDef++; 69 | 70 | return stateMachine; 71 | } 72 | 73 | // do the feedback loop 74 | void doFeedbackLoop(std::vector stateMachine) 75 | { 76 | GameSensors sensors; 77 | GameActuators actuators; 78 | 79 | while (true) 80 | { 81 | printf("Current Health %d/%d (%0.00f%%)\n", currentHealth, maximumHealth, sensors.getHealthPercent()); 82 | for (auto state = stateMachine.begin(); state != stateMachine.end(); state++) 83 | { 84 | if (!state->condition(&sensors)) 85 | { 86 | state->reach(&sensors, &actuators); 87 | break; 88 | } 89 | } 90 | 91 | getinput(); // since there's no actual game, this just allows you to change the state of the game to see how the feedback loop behaves 92 | Sleep(1000); 93 | } 94 | } 95 | 96 | int main (int argc, char *argv[]) 97 | { 98 | printf("Type a number to decrease health by that much. EG '2' dreaces health by 2. Press any other key to do nothing.\n"); 99 | doFeedbackLoop(buildMachine()); 100 | return 0; 101 | } -------------------------------------------------------------------------------- /Chapter11_StateMachines/Chapter11_StateMachines.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {F28D01D3-BDE9-4992-B3A9-9803D7294F05} 15 | Chapter11_StateMachines 16 | 17 | 18 | 19 | Application 20 | true 21 | MultiByte 22 | 23 | 24 | Application 25 | false 26 | true 27 | MultiByte 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | $(SolutionDir)\BuildTemp\$(ProjectName)_$(Configuration)\ 41 | $(SolutionDir)\bin\ 42 | 43 | 44 | $(SolutionDir)\BuildTemp\$(ProjectName)_$(Configuration)\ 45 | $(SolutionDir)\bin\DEBUG_BUILDS\ 46 | 47 | 48 | 49 | Level3 50 | Disabled 51 | 52 | 53 | true 54 | 55 | 56 | 57 | 58 | Level3 59 | MaxSpeed 60 | true 61 | true 62 | 63 | 64 | true 65 | true 66 | true 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /Chapter11_StateMachines/Chapter11_StateMachines.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | 23 | 24 | Header Files 25 | 26 | 27 | -------------------------------------------------------------------------------- /Chapter11_StateMachines/Game.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | 4 | /* 5 | THIS CODE EXISTS ONLY TO SIMULATE THE PRESENCE OF A GAME, 6 | GAME SENSORS, AND GAME ACTUATORS, AND IS NOT RELEVANT TO THE EXAMPLE CODE 7 | */ 8 | 9 | 10 | // these variables simulate the memory of the game 11 | int32_t currentHealth = 10; 12 | int32_t maximumHealth = 10; 13 | 14 | 15 | int32_t lastStrongHealAmount = 0; 16 | bool lastStrongHealFull = false; 17 | bool detectedStrongHeal = false; 18 | 19 | int32_t lastWeakHealAmount = 0; 20 | bool detectedWeakHeal = false; 21 | 22 | // this emulates our game sensors 23 | class GameSensors 24 | { 25 | public: 26 | GameSensors(){} 27 | ~GameSensors(){} 28 | 29 | float getHealthPercent() 30 | { 31 | float ch = currentHealth; 32 | float mh = maximumHealth; 33 | return ((ch / mh) * 100.00f); 34 | } 35 | 36 | bool detectedStrongHeal() 37 | { 38 | return ::detectedStrongHeal; 39 | } 40 | float getStrongHealIncrease() 41 | { 42 | float ch = lastStrongHealAmount; 43 | float mh = maximumHealth; 44 | return ((ch / mh) * 100.00f); 45 | } 46 | bool getStrongHealMaxed() 47 | { 48 | return lastStrongHealFull; 49 | } 50 | void clearStrongHealInfo() 51 | { 52 | ::detectedStrongHeal = false; 53 | } 54 | 55 | bool detectedWeakHeal() 56 | { 57 | return ::detectedWeakHeal; 58 | } 59 | float getWeakHealIncrease() 60 | { 61 | float ch = lastWeakHealAmount; 62 | float mh = maximumHealth; 63 | return ((ch / mh) * 100.00f); 64 | } 65 | }; 66 | 67 | // this emulates our game actuators 68 | class GameActuators 69 | { 70 | public: 71 | GameActuators(){} 72 | ~GameActuators(){} 73 | 74 | void strongHeal() 75 | { 76 | auto startingHealth = currentHealth; 77 | currentHealth = currentHealth + 4; 78 | currentHealth = currentHealth > maximumHealth ? maximumHealth : currentHealth; 79 | lastStrongHealAmount = currentHealth - startingHealth; 80 | lastStrongHealFull = (currentHealth == maximumHealth); 81 | detectedStrongHeal = true; 82 | printf("Doing strong heal\n"); 83 | } 84 | void weakHeal() 85 | { 86 | auto startingHealth = currentHealth; 87 | currentHealth = currentHealth + 2; 88 | currentHealth = currentHealth > maximumHealth ? maximumHealth : currentHealth; 89 | lastWeakHealAmount = currentHealth - startingHealth; 90 | detectedWeakHeal = true; 91 | printf("Doing weak heal\n"); 92 | } 93 | 94 | 95 | }; 96 | 97 | // since there's no actual game, this jsut allows you to change the state of the game to see how the feedback loop behaves 98 | void getinput() 99 | { 100 | printf("Your selection: "); 101 | auto c = getch(); 102 | if (c >= '1' && c <= '9') 103 | currentHealth -= (c - '0'); 104 | printf("%c\n", c); 105 | } -------------------------------------------------------------------------------- /Chapter1_BasicMemory/Chapter1_BasicMemory.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {AB736FAE-3FEF-40C0-B426-BFC3E3FA569F} 15 | Chapter1__01 16 | Chapter1_BasicMemory 17 | 18 | 19 | 20 | Application 21 | MultiByte 22 | true 23 | 24 | 25 | Application 26 | MultiByte 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | <_ProjectFileVersion>10.0.30319.1 40 | $(SolutionDir)\bin\DEBUG_BUILDS\ 41 | $(SolutionDir)BuildTemp\$(ProjectName)$(Configuration)\ 42 | $(SolutionDir)\bin\ 43 | $(SolutionDir)BuildTemp\$(ProjectName)$(Configuration)\ 44 | 45 | 46 | 47 | Disabled 48 | %(AdditionalIncludeDirectories) 49 | true 50 | EnableFastChecks 51 | MultiThreadedDebugDLL 52 | Level3 53 | EditAndContinue 54 | 55 | 56 | allegro-5.0.10-monolith-md-debug.lib;%(AdditionalDependencies) 57 | %(AdditionalLibraryDirectories) 58 | true 59 | Windows 60 | MachineX86 61 | 62 | 63 | copy "$(SolutionDir)game.map" "$(OutDir)game.map" /y && copy "$(SolutionDir)arial.ttf" "$(OutDir)arial.ttf" /y 64 | 65 | 66 | 67 | 68 | MaxSpeed 69 | true 70 | MultiThreadedDLL 71 | true 72 | Level3 73 | ProgramDatabase 74 | 75 | 76 | %(AdditionalDependencies) 77 | true 78 | Windows 79 | true 80 | true 81 | MachineX86 82 | 83 | 84 | copy "$(SolutionDir)game.map" "$(OutDir)game.map" /y && copy "$(SolutionDir)arial.ttf" "$(OutDir)arial.ttf" /y 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | -------------------------------------------------------------------------------- /Chapter1_BasicMemory/Chapter1_BasicMemory.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {3c8b02c5-3b42-4b99-9dbc-d301f719fc1c} 6 | 7 | 8 | {1c064fd6-e3d1-47a5-b1c0-ea67fd84ce18} 9 | 10 | 11 | 12 | 13 | Header Files 14 | 15 | 16 | 17 | 18 | Source Hiles 19 | 20 | 21 | -------------------------------------------------------------------------------- /Chapter1_BasicMemory/Location-BasicMem.h: -------------------------------------------------------------------------------- 1 | struct Location 2 | { 3 | int x; 4 | int y; 5 | 6 | Location(){} 7 | Location(int x, int y) 8 | { 9 | this->x = x; 10 | this->y = y; 11 | } 12 | const bool operator == (const Location &o) 13 | { 14 | return (o.x == this->x && o.y == this->y); 15 | } 16 | const bool operator != (const Location &o) 17 | { 18 | return !(*this == o); 19 | } 20 | const Location operator + (const Location &o) 21 | { 22 | return Location(this->x + o.x, this->y + o.y); 23 | } 24 | 25 | const Location operator - (const Location &o) 26 | { 27 | return Location(this->x - o.x, this->y - o.y); 28 | } 29 | 30 | const Location operator = (const Location &o) 31 | { 32 | this->x = o.x; 33 | this->y = o.y; 34 | return *this; 35 | } 36 | 37 | const Location operator += (const Location &o) 38 | { 39 | this->x += o.x; 40 | this->y += o.y; 41 | return *this; 42 | } 43 | 44 | const Location operator -= (const Location &o) 45 | { 46 | this->x -= o.x; 47 | this->y -= o.y; 48 | return *this; 49 | } 50 | }; -------------------------------------------------------------------------------- /Chapter1_BasicMemory/game-BasicMem.cpp: -------------------------------------------------------------------------------- 1 | #define ALLEGRO_STATICLINK 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "..\allegro_linkers.h" 10 | #include "Location-BasicMem.h" 11 | 12 | Location selfLocation(12, 16); 13 | Location ballLocation(15, 13); 14 | 15 | BYTE map[24][32]; 16 | 17 | int keys[255]; 18 | 19 | bool checkWin() 20 | { 21 | return (map[ballLocation.y][ballLocation.x] == 4); 22 | } 23 | void drawBackground() 24 | { for (int i = 0; i <= 24; i++) 25 | { 26 | for (int t = 0; t <= 32; t++) 27 | { 28 | if (map[i][t] == 1) 29 | al_draw_filled_rectangle(t * 20, i * 20, (t + 1) * 20, (i + 1) * 20, al_map_rgb(128, 255, 255)); 30 | else if(map[i][t] == 2) 31 | al_draw_filled_rectangle(t * 20, i * 20, (t + 1) * 20, (i + 1) * 20, al_map_rgb(255, 128, 0)); 32 | else if(map[i][t] == 3) 33 | al_draw_filled_rectangle(t * 20, i * 20, (t + 1) * 20, (i + 1) * 20, al_map_rgb(255, 0, 0)); 34 | else if(map[i][t] == 4) 35 | al_draw_filled_rectangle(t * 20, i * 20, (t + 1) * 20, (i + 1) * 20, al_map_rgb(0, 0, 0)); 36 | } 37 | } 38 | } 39 | 40 | void drawObjects() 41 | { 42 | al_draw_filled_rectangle(selfLocation.x * 20, selfLocation.y * 20, 43 | (selfLocation.x + 1) * 20, (selfLocation.y + 1) * 20, 44 | al_map_rgb(255, 255, 255)); 45 | al_draw_filled_circle(ballLocation.x * 20 + 10, ballLocation.y * 20 + 10, 46 | 10, al_map_rgb(100, 100, 100)); 47 | } 48 | 49 | void drawHUD(ALLEGRO_FONT *font) 50 | { 51 | al_draw_text(font, al_map_rgb(50, 50, 50), 10, 10, 0, "Arrow Keys: Move"); 52 | al_draw_text(font, al_map_rgb(50, 50, 50), 10, 25, 0, "Spacebar: Swap"); 53 | } 54 | 55 | void keyboardEvent() 56 | { 57 | Location moveOffset; 58 | if (keys[ALLEGRO_KEY_UP]) 59 | moveOffset = Location(0, -1); 60 | else if (keys[ALLEGRO_KEY_DOWN]) 61 | moveOffset = Location(0, 1); 62 | else if (keys[ALLEGRO_KEY_LEFT]) 63 | moveOffset = Location(-1, 0); 64 | else if (keys[ALLEGRO_KEY_RIGHT]) 65 | moveOffset = Location(1, 0); 66 | else if (keys[ALLEGRO_KEY_SPACE]) 67 | { 68 | moveOffset = ballLocation - selfLocation; 69 | if (abs(moveOffset.x) + abs(moveOffset.y) <= 1) 70 | { 71 | moveOffset = selfLocation; //placehold 72 | selfLocation = ballLocation; 73 | ballLocation = moveOffset; 74 | } 75 | return; 76 | } 77 | else 78 | return; 79 | 80 | Location newSelf = selfLocation + moveOffset; 81 | Location newBall = ballLocation; 82 | 83 | if (newSelf == newBall) 84 | newBall += moveOffset; 85 | 86 | if (map[newBall.y][newBall.x] == 1 || map[newSelf.y][newSelf.x] == 1) 87 | return; 88 | 89 | ballLocation = newBall; 90 | selfLocation = newSelf; 91 | } 92 | 93 | int main(void) 94 | { 95 | char* error = ""; 96 | ALLEGRO_DISPLAY *display = NULL; 97 | ALLEGRO_FONT *font = NULL; 98 | ALLEGRO_TIMER *timer = NULL; 99 | ALLEGRO_EVENT_QUEUE *event_queue = NULL; 100 | 101 | do 102 | { 103 | ZeroMemory(&keys, 255); 104 | 105 | FILE* file = fopen("game.map", "rb"); 106 | if (!file) 107 | { 108 | error = "failed to initialize map!"; 109 | break; 110 | } 111 | else 112 | { 113 | fread(map, 1, 24*32, file); 114 | fclose(file); 115 | } 116 | 117 | if(!al_init()) 118 | { 119 | error = "failed to initialize allegro!"; 120 | break; 121 | } 122 | if(!al_init_primitives_addon()) 123 | { 124 | error = "failed to initialize primitives!"; 125 | break; 126 | } 127 | al_init_font_addon(); 128 | if(!al_init_ttf_addon()) 129 | { 130 | error = "failed to initialize ttfs!"; 131 | break; 132 | } 133 | if(!al_install_keyboard()) 134 | { 135 | error = "failed to initialize keyboard!"; 136 | break; 137 | } 138 | if(!(font = al_load_ttf_font("arial.ttf", 18, 0))) 139 | { 140 | error = "failed to initialize font!"; 141 | break; 142 | } 143 | if(!(timer = al_create_timer(1.0 / 10))) 144 | { 145 | error = "failed to initialize timer!"; 146 | break; 147 | } 148 | if(!(display = al_create_display(640, 480))) 149 | { 150 | error = "failed to initialize display!"; 151 | break; 152 | } 153 | if(!(event_queue = al_create_event_queue())) 154 | { 155 | error = "failed to initialize event_queue!"; 156 | break; 157 | } 158 | 159 | al_register_event_source(event_queue, al_get_display_event_source(display)); 160 | al_register_event_source(event_queue, al_get_keyboard_event_source()); 161 | al_register_event_source(event_queue, al_get_timer_event_source(timer)); 162 | 163 | al_start_timer(timer); 164 | 165 | 166 | while(1) 167 | { 168 | ALLEGRO_EVENT ev; 169 | al_wait_for_event(event_queue, &ev); 170 | 171 | if (ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE) 172 | { 173 | break; 174 | } 175 | else if (ev.type == ALLEGRO_EVENT_KEY_DOWN) 176 | { 177 | if (ev.keyboard.keycode == ALLEGRO_KEY_ESCAPE) 178 | break; 179 | else if (ev.keyboard.keycode <= 255) 180 | keys[ev.keyboard.keycode] = true; 181 | } 182 | else if (ev.type == ALLEGRO_EVENT_KEY_UP) 183 | { 184 | if (ev.keyboard.keycode <= 255) 185 | keys[ev.keyboard.keycode] = false; 186 | } 187 | else if (ev.type == ALLEGRO_EVENT_KEY_CHAR) 188 | keyboardEvent(); 189 | 190 | if (al_is_event_queue_empty(event_queue)) 191 | { 192 | al_clear_to_color(al_map_rgb(255, 255, 255)); 193 | drawBackground(); 194 | drawObjects(); 195 | 196 | if (checkWin()) 197 | { 198 | al_draw_text(font, al_map_rgb(200, 200, 200), 320, 240, 1, "Good job! You've completed the first lab!"); 199 | al_flip_display(); 200 | continue; 201 | } 202 | 203 | drawHUD(font); 204 | al_flip_display(); 205 | } 206 | } 207 | } while (0); 208 | 209 | if (strlen(error) > 0) 210 | { 211 | al_show_native_message_box(NULL, NULL, "error", error, NULL, NULL); 212 | return -1; 213 | } 214 | 215 | al_destroy_timer(timer); 216 | al_destroy_display(display); 217 | al_destroy_event_queue(event_queue); 218 | 219 | return 0; 220 | } 221 | 222 | 223 | -------------------------------------------------------------------------------- /Chapter1_MemoryPointers/Chapter1_MemoryPointers.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {3DEAB7C6-98B4-43F0-8F71-001EB28CAE84} 15 | Chapter1__01 16 | Chapter1_MemoryPointers 17 | 18 | 19 | 20 | Application 21 | MultiByte 22 | true 23 | 24 | 25 | Application 26 | MultiByte 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | <_ProjectFileVersion>10.0.30319.1 40 | $(SolutionDir)\bin\DEBUG_BUILDS\ 41 | $(SolutionDir)BuildTemp\$(ProjectName)$(Configuration)\ 42 | $(SolutionDir)\bin\ 43 | $(SolutionDir)BuildTemp\$(ProjectName)$(Configuration)\ 44 | 45 | 46 | 47 | Disabled 48 | %(AdditionalIncludeDirectories) 49 | true 50 | EnableFastChecks 51 | MultiThreadedDebugDLL 52 | Level3 53 | EditAndContinue 54 | 55 | 56 | allegro-5.0.10-monolith-md-debug.lib;%(AdditionalDependencies) 57 | %(AdditionalLibraryDirectories) 58 | true 59 | Windows 60 | MachineX86 61 | 62 | 63 | copy "$(SolutionDir)game.map" "$(OutDir)game.map" /y && copy "$(SolutionDir)arial.ttf" "$(OutDir)arial.ttf" /y 64 | 65 | 66 | 67 | 68 | Disabled 69 | true 70 | MultiThreadedDLL 71 | true 72 | Level3 73 | ProgramDatabase 74 | 75 | 76 | %(AdditionalDependencies) 77 | true 78 | Windows 79 | true 80 | true 81 | MachineX86 82 | 83 | 84 | copy "$(SolutionDir)game.map" "$(OutDir)game.map" /y && copy "$(SolutionDir)arial.ttf" "$(OutDir)arial.ttf" /y 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | -------------------------------------------------------------------------------- /Chapter1_MemoryPointers/Chapter2_MemoryPointers.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | {3c8b02c5-3b42-4b99-9dbc-d301f719fc1c} 9 | 10 | 11 | {1c064fd6-e3d1-47a5-b1c0-ea67fd84ce18} 12 | 13 | 14 | 15 | 16 | Header Files 17 | 18 | 19 | -------------------------------------------------------------------------------- /Chapter1_MemoryPointers/Location-MemPointer.h: -------------------------------------------------------------------------------- 1 | struct Location 2 | { 3 | int x; 4 | int y; 5 | 6 | Location(){} 7 | Location(int x, int y) 8 | { 9 | this->x = x; 10 | this->y = y; 11 | } 12 | const bool operator == (const Location &o) 13 | { 14 | return (o.x == this->x && o.y == this->y); 15 | } 16 | const bool operator != (const Location &o) 17 | { 18 | return !(*this == o); 19 | } 20 | const Location operator + (const Location &o) 21 | { 22 | return Location(this->x + o.x, this->y + o.y); 23 | } 24 | 25 | const Location operator - (const Location &o) 26 | { 27 | return Location(this->x - o.x, this->y - o.y); 28 | } 29 | 30 | const Location operator = (const Location &o) 31 | { 32 | this->x = o.x; 33 | this->y = o.y; 34 | return *this; 35 | } 36 | 37 | const Location operator += (const Location &o) 38 | { 39 | this->x += o.x; 40 | this->y += o.y; 41 | return *this; 42 | } 43 | 44 | const Location operator -= (const Location &o) 45 | { 46 | this->x -= o.x; 47 | this->y -= o.y; 48 | return *this; 49 | } 50 | }; 51 | 52 | class LocationPointerSimulator 53 | { 54 | public: 55 | ~LocationPointerSimulator() 56 | { 57 | delete this->step->step->location; 58 | delete this->step->step; 59 | delete this->step; 60 | } 61 | 62 | Location* getLocation() 63 | { 64 | return step->step->location; 65 | } 66 | static LocationPointerSimulator* NewLocationPointer(Location* loc) 67 | { 68 | LocationPointerSimulator* locationPointer1 = new LocationPointerSimulator(); 69 | LocationPointerSimulator2* locationPointer2 = new LocationPointerSimulator2(); 70 | LocationPointerSimulator3* locationPointer3 = new LocationPointerSimulator3(); 71 | locationPointer3->location = loc; 72 | 73 | locationPointer1->step = locationPointer2; 74 | locationPointer2->step = locationPointer3; 75 | return locationPointer1; 76 | } 77 | 78 | private: 79 | struct LocationPointerSimulator3 80 | { 81 | char placeholders[32]; 82 | Location* location; 83 | }; 84 | 85 | struct LocationPointerSimulator2 86 | { 87 | char placeholders[64]; 88 | LocationPointerSimulator3* step; 89 | }; 90 | 91 | char placeholders[128]; 92 | LocationPointerSimulator2* step; 93 | }; 94 | -------------------------------------------------------------------------------- /Chapter2_BasicDebugging/Chapter2_BasicDebugging.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | {3c8b02c5-3b42-4b99-9dbc-d301f719fc1c} 9 | 10 | 11 | {1c064fd6-e3d1-47a5-b1c0-ea67fd84ce18} 12 | 13 | 14 | 15 | 16 | Header Files 17 | 18 | 19 | -------------------------------------------------------------------------------- /Chapter2_BasicDebugging/Chapter2_BasicDebugging.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {DEDDE9C4-3230-433C-B829-BE8981E645C9} 15 | Chapter1__01 16 | Chapter2_BasicDebugging 17 | 18 | 19 | 20 | Application 21 | MultiByte 22 | true 23 | 24 | 25 | Application 26 | MultiByte 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | <_ProjectFileVersion>10.0.30319.1 40 | $(SolutionDir)\bin\DEBUG_BUILDS\ 41 | $(SolutionDir)BuildTemp\$(ProjectName)$(Configuration)\ 42 | $(SolutionDir)\bin\ 43 | $(SolutionDir)BuildTemp\$(ProjectName)$(Configuration)\ 44 | 45 | 46 | 47 | Disabled 48 | %(AdditionalIncludeDirectories) 49 | true 50 | EnableFastChecks 51 | MultiThreadedDebugDLL 52 | Level3 53 | EditAndContinue 54 | 55 | 56 | allegro-5.0.10-monolith-md-debug.lib;%(AdditionalDependencies) 57 | %(AdditionalLibraryDirectories) 58 | true 59 | Windows 60 | MachineX86 61 | 62 | 63 | 64 | 65 | Disabled 66 | true 67 | MultiThreadedDLL 68 | true 69 | Level3 70 | ProgramDatabase 71 | 72 | 73 | %(AdditionalDependencies) 74 | true 75 | Windows 76 | true 77 | true 78 | MachineX86 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | -------------------------------------------------------------------------------- /Chapter2_BasicDebugging/Location-BasicDebugging.h: -------------------------------------------------------------------------------- 1 | struct Location 2 | { 3 | int x; 4 | int y; 5 | 6 | Location(){} 7 | Location(int x, int y) 8 | { 9 | this->x = x; 10 | this->y = y; 11 | } 12 | const bool operator == (const Location &o) 13 | { 14 | return (o.x == this->x && o.y == this->y); 15 | } 16 | const bool operator != (const Location &o) 17 | { 18 | return !(*this == o); 19 | } 20 | const Location operator + (const Location &o) 21 | { 22 | return Location(this->x + o.x, this->y + o.y); 23 | } 24 | 25 | const Location operator - (const Location &o) 26 | { 27 | return Location(this->x - o.x, this->y - o.y); 28 | } 29 | 30 | const Location operator = (const Location &o) 31 | { 32 | this->x = o.x; 33 | this->y = o.y; 34 | return *this; 35 | } 36 | 37 | const Location operator += (const Location &o) 38 | { 39 | this->x += o.x; 40 | this->y += o.y; 41 | return *this; 42 | } 43 | 44 | const Location operator -= (const Location &o) 45 | { 46 | this->x -= o.x; 47 | this->y -= o.y; 48 | return *this; 49 | } 50 | }; -------------------------------------------------------------------------------- /Chapter2_BasicDebugging/game-BasicDebugging.cpp: -------------------------------------------------------------------------------- 1 | #define ALLEGRO_STATICLINK 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include "..\allegro_linkers.h" 10 | #include "Location-BasicDebugging.h" 11 | 12 | 13 | Location ballLocation(10, 20); 14 | Location ballIncrement(6, 3); 15 | 16 | 17 | void drawFrame(ALLEGRO_FONT *font) 18 | { 19 | ballLocation.x += ballIncrement.x; 20 | ballLocation.y += ballIncrement.y; 21 | 22 | if (ballLocation.x > 630 || ballLocation.x < 10) 23 | ballIncrement.x = ballIncrement.x * -1; 24 | 25 | if (ballLocation.y > 470 || ballLocation.y < 10) 26 | ballIncrement.y = ballIncrement.y * -1; 27 | 28 | al_clear_to_color(al_map_rgb(128, 128, 255)); 29 | 30 | al_draw_filled_rectangle(320, 0, 321, 480, al_map_rgb(166, 166, 166)); 31 | 32 | if (ballLocation.x >= 320) 33 | { 34 | al_draw_filled_rectangle(ballLocation.x-1, 0, ballLocation.x+1, 480, al_map_rgb(196, 196, 196)); 35 | al_draw_text(font, al_map_rgb(50, 50, 50), 10, 10, 0, "Ball hidden.."); 36 | } 37 | else 38 | al_draw_filled_circle(ballLocation.x, ballLocation.y, 10, al_map_rgb(100, 100, 100)); 39 | 40 | al_flip_display(); 41 | } 42 | 43 | int main(void) 44 | { 45 | char* error = ""; 46 | ALLEGRO_DISPLAY *display = NULL; 47 | ALLEGRO_FONT *font = NULL; 48 | ALLEGRO_TIMER *timer = NULL; 49 | ALLEGRO_EVENT_QUEUE *event_queue = NULL; 50 | 51 | do 52 | { 53 | if(!al_init()) 54 | { 55 | error = "failed to initialize allegro!"; 56 | break; 57 | } 58 | if(!al_init_primitives_addon()) 59 | { 60 | error = "failed to initialize primitives!"; 61 | break; 62 | } 63 | al_init_font_addon(); 64 | if(!al_init_ttf_addon()) 65 | { 66 | error = "failed to initialize ttfs!"; 67 | break; 68 | } 69 | if(!(font = al_load_ttf_font("arial.ttf", 18, 0))) 70 | { 71 | error = "failed to initialize font!"; 72 | break; 73 | } 74 | if(!(timer = al_create_timer(1.0 / 20))) 75 | { 76 | error = "failed to initialize timer!"; 77 | break; 78 | } 79 | if(!(display = al_create_display(640, 480))) 80 | { 81 | error = "failed to initialize display!"; 82 | break; 83 | } 84 | if(!(event_queue = al_create_event_queue())) 85 | { 86 | error = "failed to initialize event_queue!"; 87 | break; 88 | } 89 | 90 | al_register_event_source(event_queue, al_get_display_event_source(display)); 91 | al_register_event_source(event_queue, al_get_timer_event_source(timer)); 92 | 93 | al_start_timer(timer); 94 | 95 | while(1) 96 | { 97 | ALLEGRO_EVENT ev; 98 | al_wait_for_event(event_queue, &ev); 99 | 100 | if (ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE) 101 | break; 102 | 103 | if (al_is_event_queue_empty(event_queue)) 104 | drawFrame(font); 105 | } 106 | } while (0); 107 | 108 | if (strlen(error) > 0) 109 | { 110 | al_show_native_message_box(NULL, NULL, "error", error, NULL, NULL); 111 | return -1; 112 | } 113 | 114 | al_destroy_timer(timer); 115 | al_destroy_display(display); 116 | al_destroy_event_queue(event_queue); 117 | 118 | return 0; 119 | } -------------------------------------------------------------------------------- /Chapter3_CloseMutex/Chapter3_CloseMutex.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | {3c8b02c5-3b42-4b99-9dbc-d301f719fc1c} 9 | 10 | 11 | {1c064fd6-e3d1-47a5-b1c0-ea67fd84ce18} 12 | 13 | 14 | 15 | 16 | Header Files 17 | 18 | 19 | -------------------------------------------------------------------------------- /Chapter3_CloseMutex/Chapter3_CloseMutex.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {B7A15C0B-6532-432F-864B-5381256B4D58} 15 | Chapter1__01 16 | Chapter3_CloseMutex 17 | 18 | 19 | 20 | Application 21 | MultiByte 22 | true 23 | 24 | 25 | Application 26 | MultiByte 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | <_ProjectFileVersion>10.0.30319.1 40 | $(SolutionDir)\bin\DEBUG_BUILDS\ 41 | $(SolutionDir)BuildTemp\$(ProjectName)$(Configuration)\ 42 | $(SolutionDir)\bin\ 43 | $(SolutionDir)BuildTemp\$(ProjectName)$(Configuration)\ 44 | 45 | 46 | 47 | Disabled 48 | %(AdditionalIncludeDirectories) 49 | true 50 | EnableFastChecks 51 | MultiThreadedDebugDLL 52 | Level3 53 | EditAndContinue 54 | 55 | 56 | allegro-5.0.10-monolith-md-debug.lib;%(AdditionalDependencies) 57 | %(AdditionalLibraryDirectories) 58 | true 59 | Windows 60 | MachineX86 61 | 62 | 63 | 64 | 65 | Disabled 66 | true 67 | MultiThreadedDLL 68 | true 69 | Level3 70 | ProgramDatabase 71 | 72 | 73 | %(AdditionalDependencies) 74 | true 75 | Windows 76 | true 77 | true 78 | MachineX86 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | -------------------------------------------------------------------------------- /Chapter3_CloseMutex/Location-CloseMutex.h: -------------------------------------------------------------------------------- 1 | struct Location 2 | { 3 | int x; 4 | int y; 5 | 6 | Location(){} 7 | Location(int x, int y) 8 | { 9 | this->x = x; 10 | this->y = y; 11 | } 12 | const bool operator == (const Location &o) 13 | { 14 | return (o.x == this->x && o.y == this->y); 15 | } 16 | const bool operator != (const Location &o) 17 | { 18 | return !(*this == o); 19 | } 20 | const Location operator + (const Location &o) 21 | { 22 | return Location(this->x + o.x, this->y + o.y); 23 | } 24 | 25 | const Location operator - (const Location &o) 26 | { 27 | return Location(this->x - o.x, this->y - o.y); 28 | } 29 | 30 | const Location operator = (const Location &o) 31 | { 32 | this->x = o.x; 33 | this->y = o.y; 34 | return *this; 35 | } 36 | 37 | const Location operator += (const Location &o) 38 | { 39 | this->x += o.x; 40 | this->y += o.y; 41 | return *this; 42 | } 43 | 44 | const Location operator -= (const Location &o) 45 | { 46 | this->x -= o.x; 47 | this->y -= o.y; 48 | return *this; 49 | } 50 | }; -------------------------------------------------------------------------------- /Chapter3_FindingFiles/Chapter3_FindingFiles.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | {3c8b02c5-3b42-4b99-9dbc-d301f719fc1c} 9 | 10 | 11 | {1c064fd6-e3d1-47a5-b1c0-ea67fd84ce18} 12 | 13 | 14 | 15 | 16 | Header Files 17 | 18 | 19 | -------------------------------------------------------------------------------- /Chapter3_FindingFiles/Chapter3_FindingFiles.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {4188B6F0-3948-4CB8-90C6-038CED132E11} 15 | Chapter1__01 16 | Chapter3_FindingFiles 17 | 18 | 19 | 20 | Application 21 | MultiByte 22 | true 23 | 24 | 25 | Application 26 | MultiByte 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | <_ProjectFileVersion>10.0.30319.1 40 | $(SolutionDir)\bin\DEBUG_BUILDS\ 41 | $(SolutionDir)BuildTemp\$(ProjectName)$(Configuration)\ 42 | $(SolutionDir)\bin\ 43 | $(SolutionDir)BuildTemp\$(ProjectName)$(Configuration)\ 44 | 45 | 46 | 47 | Disabled 48 | %(AdditionalIncludeDirectories) 49 | true 50 | EnableFastChecks 51 | MultiThreadedDebugDLL 52 | Level3 53 | EditAndContinue 54 | 55 | 56 | allegro-5.0.10-monolith-md-debug.lib;%(AdditionalDependencies) 57 | %(AdditionalLibraryDirectories) 58 | true 59 | Windows 60 | MachineX86 61 | 62 | 63 | 64 | 65 | Disabled 66 | true 67 | MultiThreadedDLL 68 | true 69 | Level3 70 | ProgramDatabase 71 | 72 | 73 | %(AdditionalDependencies) 74 | true 75 | Windows 76 | true 77 | true 78 | MachineX86 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | -------------------------------------------------------------------------------- /Chapter3_FindingFiles/Location-FindingFiles.h: -------------------------------------------------------------------------------- 1 | struct Location 2 | { 3 | int x; 4 | int y; 5 | 6 | Location(){} 7 | Location(int x, int y) 8 | { 9 | this->x = x; 10 | this->y = y; 11 | } 12 | const bool operator == (const Location &o) 13 | { 14 | return (o.x == this->x && o.y == this->y); 15 | } 16 | const bool operator != (const Location &o) 17 | { 18 | return !(*this == o); 19 | } 20 | const Location operator + (const Location &o) 21 | { 22 | return Location(this->x + o.x, this->y + o.y); 23 | } 24 | 25 | const Location operator - (const Location &o) 26 | { 27 | return Location(this->x - o.x, this->y - o.y); 28 | } 29 | 30 | const Location operator = (const Location &o) 31 | { 32 | this->x = o.x; 33 | this->y = o.y; 34 | return *this; 35 | } 36 | 37 | const Location operator += (const Location &o) 38 | { 39 | this->x += o.x; 40 | this->y += o.y; 41 | return *this; 42 | } 43 | 44 | const Location operator -= (const Location &o) 45 | { 46 | this->x -= o.x; 47 | this->y -= o.y; 48 | return *this; 49 | } 50 | }; -------------------------------------------------------------------------------- /Chapter4_CodeToMemory/Chapter4_CodeToMemory.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /Chapter4_CodeToMemory/Chapter4_CodeToMemory.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {42D11C4C-AC06-47BD-B6CD-FC6DBAF54472} 15 | Win32Proj 16 | Chapter4_CodeToMemory 17 | Chapter4_CodeToMemory 18 | 19 | 20 | 21 | Application 22 | true 23 | Unicode 24 | 25 | 26 | Application 27 | false 28 | true 29 | Unicode 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | true 43 | $(SolutionDir)\BuildTemp\$(ProjectName)_$(Configuration)\ 44 | $(SolutionDir)\bin\DEBUG_BUILDS\ 45 | 46 | 47 | false 48 | $(SolutionDir)\BuildTemp\$(ProjectName)_$(Configuration)\ 49 | $(SolutionDir)\bin\ 50 | 51 | 52 | 53 | 54 | 55 | Level3 56 | Disabled 57 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 58 | 4Bytes 59 | 60 | 61 | Console 62 | true 63 | false 64 | 65 | 66 | 67 | 68 | Level3 69 | 70 | 71 | Disabled 72 | true 73 | true 74 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 75 | 4Bytes 76 | 77 | 78 | Console 79 | true 80 | true 81 | true 82 | 83 | 84 | false 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | -------------------------------------------------------------------------------- /Chapter4_CodeToMemory/main-codeToMemory.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | /* numeric values */ 5 | unsigned char ubyteValue = 0xFF; 6 | char byteValue = 0xFE; 7 | 8 | unsigned short uwordValue = 0x4142; 9 | short wordValue = 0x4344; 10 | 11 | unsigned int udwordValue = 0xDEADBEEF; 12 | int dwordValue = 0xDEADBEEF; 13 | 14 | unsigned long long ulongLongValue = 0xEFCDAB8967452301; 15 | long long longLongValue = 0xEFCDAB8967452301; 16 | 17 | float floatValue = 1337.7331; 18 | 19 | /* string values */ 20 | char* thinStringP = "my_thin_terminated_value_pointer"; 21 | char thinStringA[40] = "my_thin_terminated_value_array"; 22 | wchar_t* wideStringP = L"my_wide_terminated_value_pointer"; 23 | wchar_t wideStringA[40] = L"my_wide_terminated_value_array"; 24 | 25 | /* structures */ 26 | struct MyStruct { 27 | unsigned char ubyteValue; 28 | char byteValue; 29 | unsigned short uwordValue; 30 | short wordValue; 31 | unsigned int udwordValue; 32 | int dwordValue; 33 | unsigned long long ulongLongValue; 34 | char interruptor; 35 | long long longLongValue; 36 | float floatValue; 37 | }; 38 | 39 | /* classes with no VF tables */ 40 | class bar { 41 | public: 42 | bar() : bar1(0x898989), bar2(0x10203040) {} 43 | void myfunction() { bar1++; } 44 | int bar1, bar2; 45 | }; 46 | 47 | /* classes with VF tables */ 48 | class foo { 49 | public: 50 | foo() : myValue1(0xDEADBEEF), myValue2(0xBABABABA) {} 51 | int myValue1; 52 | static int myStaticValue; 53 | virtual void bar() { printf("foo::bar()\n"); } 54 | virtual void baz() { printf("foo::baz()\n"); } 55 | virtual void barbaz() {} 56 | int myValue2; 57 | }; 58 | int foo::myStaticValue = 0x12121212; 59 | class fooa : public foo { 60 | public: 61 | fooa() : foo() {} 62 | virtual void bar() { printf("fooa::bar()\n"); } 63 | virtual void baz() { printf("fooa::baz()\n"); } 64 | }; 65 | class foob : public foo { 66 | public: 67 | foob() : foo() { } 68 | virtual void bar() { printf("foob::bar()\n"); } 69 | virtual void baz() { printf("foob::baz()\n"); } 70 | }; 71 | 72 | /* class protection */ 73 | class baz { 74 | public: 75 | baz() : baz1(0x11111111), baz2(0x22222222), 76 | baz3(0x33333333), baz4(0x44444444) {} 77 | int baz1, baz2; 78 | void printStuff() 79 | { 80 | printf("0x%x : baz->baz1\n", &this->baz1); 81 | printf("0x%x : baz->baz2\n", &this->baz2); 82 | printf("0x%x : baz->baz3\n", &this->baz3); 83 | printf("0x%x : baz->baz4\n", &this->baz4); 84 | } 85 | private: 86 | int baz3, baz4; 87 | }; 88 | 89 | int main(void) 90 | { 91 | /* just using global values so they don't get optimized away */ 92 | ubyteValue = ubyteValue; 93 | byteValue = byteValue; 94 | wordValue = wordValue; 95 | uwordValue = uwordValue; 96 | udwordValue = udwordValue; 97 | dwordValue = dwordValue; 98 | ulongLongValue = ulongLongValue; 99 | longLongValue = longLongValue; 100 | floatValue = floatValue; 101 | 102 | thinStringP = thinStringP; 103 | if (thinStringA){} 104 | wideStringP = wideStringP; 105 | if (wideStringA){} 106 | 107 | /* printing addresses so we can easily find the dumps */ 108 | printf("0x%x : ubyteValue\n", &ubyteValue); 109 | printf("0x%x : thinStringP\n", &thinStringP); 110 | 111 | /* showing structure arrangement */ 112 | MyStruct* m = 0; 113 | printf("Offsets: %d,%d,%d,%d,%d,%d,%d,%d,%d\n", 114 | &m->ubyteValue, &m->byteValue, 115 | &m->uwordValue, &m->wordValue, 116 | &m->udwordValue, &m->dwordValue, 117 | &m->ulongLongValue, &m->longLongValue, 118 | &m->floatValue); 119 | 120 | /* union stuff */ 121 | union { 122 | BYTE byteValue; 123 | struct { 124 | WORD first; 125 | WORD second; 126 | } words; 127 | DWORD value; 128 | } dwValue; 129 | dwValue.value = 0xDEADBEEF; 130 | printf("Size %d; Addresses 0x%x,0x%x; Values 0x%x,0x%x\n", 131 | sizeof(dwValue), &dwValue.value, &dwValue.words, 132 | dwValue.words.first, dwValue.words.second); 133 | 134 | /* classes with no VF tables */ 135 | bar _bar = bar(); 136 | printf("Size %d; Address 0x%x : _bar\n", sizeof(_bar), &_bar); 137 | 138 | /* class VF call */ 139 | foo* _testfoo = (foo*)new fooa(); 140 | _testfoo->bar(); 141 | 142 | /* classes with VF tables */ 143 | foo _foo = foo(); 144 | fooa _fooa = fooa(); 145 | foob _foob = foob(); 146 | printf("0x%x : _foo\n", &_foo); 147 | printf("0x%x : _fooa\n", &_fooa); 148 | printf("0x%x : _foob\n", &_foob); 149 | 150 | _foo.barbaz(); 151 | _fooa.bar(); 152 | _foob.baz(); 153 | 154 | /* class protection */ 155 | baz* _baz = 0; 156 | _baz->printStuff(); 157 | 158 | system("pause"); 159 | } -------------------------------------------------------------------------------- /Chapter5_AdvancedMemoryForensics_Scanning/Chapter5_AdvancedMemoryForensics_Scanning.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {6C658EF9-CCA4-4E18-8AD7-CEBDC04AB3AB} 15 | Win32Proj 16 | Chapter5_AdvancedMemoryForensics_Scanning 17 | 18 | 19 | 20 | Application 21 | true 22 | Unicode 23 | 24 | 25 | Application 26 | false 27 | true 28 | Unicode 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | true 42 | $(SolutionDir)\BuildTemp\$(ProjectName)_$(Configuration)\ 43 | $(SolutionDir)\bin\DEBUG_BUILDS\ 44 | 45 | 46 | false 47 | $(SolutionDir)\BuildTemp\$(ProjectName)_$(Configuration)\ 48 | $(SolutionDir)\bin\ 49 | 50 | 51 | 52 | 53 | 54 | Level3 55 | Disabled 56 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 57 | 4Bytes 58 | 59 | 60 | Console 61 | true 62 | false 63 | 64 | 65 | 66 | 67 | Level3 68 | 69 | 70 | Disabled 71 | true 72 | true 73 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 74 | 4Bytes 75 | 76 | 77 | Console 78 | false 79 | true 80 | true 81 | 82 | 83 | false 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /Chapter5_AdvancedMemoryForensics_Scanning/main-advancedMemoryForensics-Scanning.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | struct PlayerVital { 8 | int current, maximum; 9 | }; 10 | 11 | PlayerVital health = {450, 500}; 12 | 13 | std::vector vectorData; 14 | std::list listData; 15 | 16 | typedef int keyInt; 17 | typedef int valInt; 18 | std::map mapData; 19 | 20 | 21 | void printString(const char* text, int one, int two) 22 | { 23 | printf(text, one, two); 24 | } 25 | 26 | void printHealth() 27 | { 28 | printString("Health: %d of %d\n", health.current, health.maximum); 29 | } 30 | 31 | // VECTOR 32 | 33 | void readVector(DWORD vectorAddress) 34 | { 35 | struct _vector 36 | { 37 | DWORD* begin; 38 | DWORD* end; 39 | DWORD* tail; 40 | }; 41 | 42 | _vector* vec = (_vector*)vectorAddress; 43 | 44 | DWORD count = ((DWORD)vec->end - (DWORD)vec->begin) / sizeof(DWORD); 45 | DWORD capacity = ((DWORD)vec->tail - (DWORD)vec->begin) / sizeof(DWORD); 46 | 47 | printf("Vector has %d items and %d capacity\n", count, capacity); 48 | 49 | for (int i = 0; i < count; i++) 50 | printf("\tValue at %d is %d\n", i, vec->begin[i]); 51 | } 52 | 53 | // LIST 54 | 55 | void readList(DWORD listAddress) 56 | { 57 | struct listItem 58 | { 59 | listItem* next; 60 | listItem* prev; 61 | DWORD value; 62 | }; 63 | 64 | struct _list 65 | { 66 | listItem* root; 67 | DWORD size; 68 | }; 69 | 70 | _list* list = (_list*)listAddress; 71 | 72 | printf("List has %d items\n", list->size); 73 | 74 | for (listItem* it = list->root->next; it != list->root; it = it->next) 75 | printf("\tForward value is %d\n", it->value); 76 | 77 | for (listItem* it = list->root->prev; it != list->root; it = it->prev) 78 | printf("\tReverse value is %d\n", it->value); 79 | } 80 | 81 | // MAP 82 | 83 | struct mapItem { 84 | mapItem* left; 85 | mapItem* parent; 86 | mapItem* right; 87 | keyInt key; 88 | valInt value; 89 | }; 90 | struct _map { 91 | DWORD irrelevant; 92 | mapItem* rootNode; 93 | int size; 94 | }; 95 | 96 | mapItem* findItem(keyInt key, mapItem* node, mapItem* root) 97 | { 98 | if (node != root) { 99 | if (key == node->key) 100 | return node; 101 | else if (key < node->key) 102 | return findItem(key, node->left, root); 103 | else 104 | return findItem(key, node->right, root); 105 | } 106 | else 107 | return root; 108 | } 109 | 110 | mapItem* searchMap(keyInt key, _map* map) 111 | { 112 | mapItem* ret = 113 | findItem(key, map->rootNode->parent, map->rootNode); 114 | if (ret == map->rootNode) return NULL; 115 | return ret; 116 | } 117 | 118 | 119 | void iterateMap(mapItem* node, mapItem* root) 120 | { 121 | if (node == root) return; 122 | iterateMap(node->left, root); 123 | printf("\tKey %d has value 0x%04x\n", node->key, node->value); 124 | iterateMap(node->right, root); 125 | } 126 | 127 | void readMap(DWORD mapAddress) 128 | { 129 | _map* map = (_map*)mapAddress; 130 | 131 | printf("Nodes in map: %d\n", map->size); 132 | iterateMap(map->rootNode->parent, map->rootNode); 133 | 134 | printf("\tMap search for 1 yields: 0x%04x\n", searchMap(1, map)->value); 135 | printf("\tMap search for 2 yields: 0x%04x\n", searchMap(2, map)->value); 136 | printf("\tMap search for 3 yields: 0x%04x\n", searchMap(3, map)->value); 137 | printf("\tMap search for 5 yields: 0x%04x\n", searchMap(5, map)->value); 138 | } 139 | 140 | 141 | int main(void) 142 | { 143 | vectorData.reserve(20); 144 | vectorData.push_back(12345); 145 | vectorData.push_back(54321); 146 | 147 | listData.push_back(123); 148 | listData.push_back(321); 149 | listData.push_back(121); 150 | 151 | mapData.insert(std::pair(1, 0x100)); 152 | mapData.insert(std::pair(2, 0x200)); 153 | mapData.insert(std::pair(3, 0x200)); 154 | mapData.insert(std::pair(5, 0x500)); 155 | 156 | while (true) // stupid loop to keep anything needed for the example from being optimized away 157 | { 158 | auto something = &printString; 159 | 160 | printHealth(); 161 | readVector((DWORD)&vectorData); 162 | readList((DWORD)&listData); 163 | readMap((DWORD)&mapData); 164 | 165 | health.current = (health.current == health.maximum) ? 1 : (health.current + 1); 166 | health.maximum = 500; 167 | system("pause"); 168 | } 169 | } -------------------------------------------------------------------------------- /Chapter6_AccessingMemory/Chapter6_AccessingMemory.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {4C3B87D1-43D3-44DB-913E-E4A1D99909CB} 15 | Win32Proj 16 | Chapter6_AccessingMemory 17 | Chapter6_AccessingMemory 18 | 19 | 20 | 21 | Application 22 | true 23 | Unicode 24 | 25 | 26 | Application 27 | false 28 | true 29 | Unicode 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | true 43 | $(SolutionDir)\BuildTemp\$(ProjectName)_$(Configuration)\ 44 | $(SolutionDir)\bin\DEBUG_BUILDS\ 45 | 46 | 47 | false 48 | $(SolutionDir)\BuildTemp\$(ProjectName)_$(Configuration)\ 49 | $(SolutionDir)\bin\ 50 | 51 | 52 | 53 | 54 | 55 | Level3 56 | Disabled 57 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 58 | 4Bytes 59 | 60 | 61 | Console 62 | true 63 | false 64 | 65 | 66 | 67 | 68 | Level3 69 | 70 | 71 | Disabled 72 | true 73 | true 74 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 75 | 4Bytes 76 | 77 | 78 | Console 79 | true 80 | true 81 | true 82 | 83 | 84 | false 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | -------------------------------------------------------------------------------- /Chapter6_AccessingMemory/main-accessingMemory.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | 6 | DWORD getPIDFromWindow(HWND window) 7 | { 8 | DWORD PID; 9 | GetWindowThreadProcessId(window, &PID); 10 | return PID; 11 | } 12 | 13 | DWORD getPIDByName(std::wstring name) 14 | { 15 | DWORD PID = -1; 16 | 17 | PROCESSENTRY32 entry; 18 | entry.dwSize = sizeof(PROCESSENTRY32); 19 | 20 | HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL); 21 | 22 | if (Process32First(snapshot, &entry) == TRUE) 23 | { 24 | while (Process32Next(snapshot, &entry) == TRUE) 25 | { 26 | std::wstring binaryPath = entry.szExeFile; 27 | if (binaryPath.find(name) != std::wstring::npos) 28 | { 29 | PID = entry.th32ProcessID; 30 | break; 31 | } 32 | } 33 | } 34 | 35 | CloseHandle(snapshot); 36 | return PID; 37 | } 38 | 39 | template 40 | T readMemoryAPI(HANDLE process, LPVOID address) 41 | { 42 | T value; 43 | ReadProcessMemory(process, address, &value, sizeof(T), NULL); 44 | return value; 45 | } 46 | 47 | template 48 | void writeMemoryAPI(HANDLE process, LPVOID address, T value) 49 | { 50 | WriteProcessMemory(process, address, &value, sizeof(T), NULL); 51 | } 52 | 53 | template 54 | DWORD protectMemory(HANDLE process, LPVOID address, DWORD prot) 55 | { 56 | DWORD oldProt; 57 | VirtualProtectEx(process, address, sizeof(T), prot, &oldProt); 58 | return oldProt; 59 | } 60 | 61 | void readAndWriteMemoryAPI(HANDLE process, LPVOID address) 62 | { 63 | DWORD value = readMemoryAPI(process, address); 64 | 65 | printf("Current mem value is %d\n", value); 66 | value++; 67 | 68 | DWORD oldProt = protectMemory(process, address, PAGE_READWRITE); 69 | writeMemoryAPI(process, address, value); 70 | protectMemory(process, address, oldProt); 71 | 72 | 73 | value = readMemoryAPI(process, address); 74 | 75 | printf("New mem value is %d\n", value); 76 | } 77 | 78 | template 79 | T readMemoryPointer(LPVOID address) 80 | { 81 | return *((T*)address); 82 | } 83 | 84 | template 85 | void writeMemoryPointer(LPVOID address, T value) 86 | { 87 | *((T*)address) = value; 88 | } 89 | 90 | template 91 | T* pointMemory(LPVOID address) 92 | { 93 | return ((T*)address); 94 | } 95 | void readAndWriteMemoryMarshall(LPVOID address) 96 | { 97 | DWORD value = readMemoryPointer(address); 98 | 99 | printf("Current mem value is %d\n", value); 100 | value++; 101 | 102 | writeMemoryPointer(address, value); 103 | value = readMemoryPointer(address); 104 | 105 | printf("New mem value is %d\n", value); 106 | } 107 | 108 | 109 | DWORD getMyBaseAddressGMH() 110 | { 111 | return (DWORD)GetModuleHandle(NULL); 112 | } 113 | 114 | DWORD getMyBaseAddressFS() 115 | { 116 | DWORD newBase; 117 | __asm 118 | { 119 | MOV EAX, DWORD PTR FS:[0x30] 120 | MOV EAX, DWORD PTR DS:[EAX+0x8] 121 | MOV newBase, EAX 122 | } 123 | return newBase; 124 | } 125 | 126 | DWORD getRemoteBaseAddress(HANDLE process) 127 | { 128 | DWORD newBase; 129 | // get the address of kernel32.dll 130 | HMODULE k32 = GetModuleHandleA("kernel32.dll"); 131 | 132 | // get the address of GetModuleHandle() 133 | LPVOID funcAdr = GetProcAddress(k32, "GetModuleHandleA"); 134 | if (!funcAdr) funcAdr = GetProcAddress(k32, "GetModuleHandleW"); 135 | 136 | // create the thread 137 | HANDLE thread = CreateRemoteThread(process, NULL, NULL, (LPTHREAD_START_ROUTINE)funcAdr, NULL, NULL, NULL); 138 | 139 | // let the thread finish 140 | WaitForSingleObject(thread, INFINITE); 141 | 142 | // get the exit code 143 | GetExitCodeThread(thread, &newBase); 144 | 145 | // clean up the thread handle 146 | CloseHandle(thread); 147 | 148 | return newBase; 149 | } 150 | 151 | void printMyBaseAddresses(HANDLE Process) 152 | { 153 | DWORD base1 = getMyBaseAddressGMH(); 154 | DWORD base2 = getMyBaseAddressFS(); 155 | DWORD base3 = getRemoteBaseAddress(Process); 156 | if (base1 != base2 || base2 != base3) 157 | printf("Woah, this should be impossible!\n"); 158 | else 159 | printf("My base address is 0x%08x\n", base1); 160 | } 161 | 162 | int main(void) 163 | { 164 | HANDLE proc = OpenProcess( 165 | PROCESS_VM_OPERATION | 166 | PROCESS_VM_READ | 167 | PROCESS_VM_WRITE | 168 | PROCESS_CREATE_THREAD, 169 | FALSE, GetCurrentProcessId()); 170 | 171 | printMyBaseAddresses(proc); 172 | 173 | // get my PID from window 174 | wchar_t myTitle[1024]; 175 | GetConsoleTitle(&myTitle[0], 1024); 176 | HWND myWindow = FindWindow(NULL, myTitle); 177 | 178 | auto myPID = getPIDFromWindow(myWindow); 179 | printf("My pid is %d\n", myPID); 180 | 181 | // get explorer PID by process name 182 | auto explorerPID = getPIDByName(L"explorer.exe"); 183 | printf("Explorer pid is %d\n", explorerPID); 184 | 185 | 186 | // lets do some memory stuff.. to ourself 187 | DWORD someValue = 1234; 188 | readAndWriteMemoryAPI(proc, &someValue); 189 | readAndWriteMemoryMarshall(&someValue); 190 | 191 | system("pause"); 192 | } 193 | -------------------------------------------------------------------------------- /Chapter7_CodeInjection/Chapter7_CodeInjection.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {A20C8EDD-02C5-499E-8DB6-1CB8081FD62B} 15 | Win32Proj 16 | Chapter7_CodeInjection 17 | Chapter7_CodeInjection 18 | 19 | 20 | 21 | Application 22 | true 23 | Unicode 24 | 25 | 26 | Application 27 | false 28 | true 29 | Unicode 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | true 43 | $(SolutionDir)\BuildTemp\$(ProjectName)_$(Configuration)\ 44 | $(SolutionDir)\bin\DEBUG_BUILDS\ 45 | 46 | 47 | false 48 | $(SolutionDir)\BuildTemp\$(ProjectName)_$(Configuration)\ 49 | $(SolutionDir)\bin\ 50 | 51 | 52 | 53 | 54 | 55 | Level3 56 | Disabled 57 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 58 | 4Bytes 59 | 60 | 61 | Console 62 | true 63 | false 64 | 65 | 66 | 67 | 68 | Level3 69 | 70 | 71 | Disabled 72 | true 73 | true 74 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 75 | 4Bytes 76 | 77 | 78 | Console 79 | true 80 | true 81 | true 82 | 83 | 84 | false 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | -------------------------------------------------------------------------------- /Chapter7_CodeInjection/main-codeInjection.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | 6 | DWORD printStringManyTimes(int times, const char* string) 7 | { 8 | for (int i = 0; i < times; i++) 9 | printf(string); 10 | return 0; 11 | } 12 | 13 | 14 | void injectCodeUsingThreadInjection(HANDLE process, LPVOID func, int times, const char* string) 15 | { 16 | BYTE codeCave[20] = { 17 | 0xFF, 0x74, 0x24, 0x04, // PUSH DWORD PTR[ESP+0x4] 18 | 0x68, 0x00, 0x00, 0x00, 0x00, // PUSH 0 19 | 0xB8, 0x00, 0x00, 0x00, 0x00, // MOV EAX, 0x0 20 | 0xFF, 0xD0, // CALL EAX 21 | 0x83, 0xC4, 0x08, // ADD ESP, 0x08 22 | 0xC3 // RETN 23 | }; 24 | 25 | // copy values to the shellcode 26 | memcpy(&codeCave[5], ×, 4); 27 | memcpy(&codeCave[10], &func, 4); 28 | 29 | 30 | // allocate memory for the code cave 31 | int stringlen = strlen(string) + 1; 32 | int fulllen = stringlen + sizeof(codeCave); 33 | LPVOID remoteString = VirtualAllocEx(process, NULL, fulllen, MEM_COMMIT, PAGE_EXECUTE); 34 | LPVOID remoteCave = (LPVOID)((DWORD)remoteString + stringlen); 35 | 36 | // write the code cave 37 | WriteProcessMemory(process, remoteString, string, stringlen, NULL); 38 | WriteProcessMemory(process, remoteCave, codeCave, sizeof(codeCave), NULL); 39 | 40 | // run the thread 41 | HANDLE thread = CreateRemoteThread(process, NULL, NULL, 42 | (LPTHREAD_START_ROUTINE)remoteCave, 43 | remoteString, NULL, NULL); 44 | WaitForSingleObject(thread, INFINITE); 45 | CloseHandle(thread); 46 | } 47 | 48 | 49 | DWORD GetProcessThreadID(HANDLE Process) 50 | { 51 | THREADENTRY32 entry; 52 | entry.dwSize = sizeof(THREADENTRY32); 53 | HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0); 54 | 55 | if (Thread32First(snapshot, &entry) == TRUE) 56 | { 57 | DWORD PID = GetProcessId(Process); 58 | while (Thread32Next(snapshot, &entry) == TRUE) 59 | { 60 | if (entry.th32OwnerProcessID == PID) 61 | { 62 | CloseHandle(snapshot); 63 | return entry.th32ThreadID; 64 | } 65 | } 66 | } 67 | CloseHandle(snapshot); 68 | return NULL; 69 | } 70 | 71 | 72 | 73 | void injectCodeUsingThreadHijacking(HANDLE process, LPVOID func, int times, const char* string) 74 | { 75 | BYTE codeCave[31] = { 76 | 0x60, //PUSHAD 77 | 0x9C, //PUSHFD 78 | 0x68, 0x00, 0x00, 0x00, 0x00, // PUSH 0 79 | 0x68, 0x00, 0x00, 0x00, 0x00, // PUSH 0 80 | 0xB8, 0x00, 0x00, 0x00, 0x00, // MOV EAX, 0x0 81 | 0xFF, 0xD0, // CALL EAX 82 | 0x83, 0xC4, 0x08, // ADD ESP, 0x08 83 | 0x9D, //POPFD 84 | 0x61, //POPAD 85 | 0x68, 0x00, 0x00, 0x00, 0x00, // PUSH 0 86 | 0xC3 // RETN 87 | }; 88 | 89 | // allocate memory for the coe cave 90 | int stringlen = strlen(string) + 1; 91 | int fulllen = stringlen + sizeof(codeCave); 92 | LPVOID remoteString = VirtualAllocEx(process, NULL, fulllen, MEM_COMMIT, PAGE_EXECUTE); 93 | LPVOID remoteCave = (LPVOID)((DWORD)remoteString + stringlen); 94 | 95 | // suspend the thread and query its control context 96 | DWORD threadID = GetProcessThreadID(process); 97 | HANDLE thread = OpenThread((THREAD_GET_CONTEXT | THREAD_SUSPEND_RESUME | THREAD_SET_CONTEXT), false, threadID); 98 | SuspendThread(thread); 99 | 100 | CONTEXT threadContext; 101 | threadContext.ContextFlags = CONTEXT_CONTROL; 102 | GetThreadContext(thread, &threadContext); 103 | 104 | // copy values to the shellcode (happens late because we need values from allocation) 105 | memcpy(&codeCave[3], &remoteString, 4); 106 | memcpy(&codeCave[8], ×, 4); 107 | memcpy(&codeCave[13], &func, 4); 108 | memcpy(&codeCave[25], &threadContext.Eip, 4); 109 | 110 | 111 | // write the code cave 112 | WriteProcessMemory(process, remoteString, string, stringlen, NULL); 113 | WriteProcessMemory(process, remoteCave, codeCave, sizeof(codeCave), NULL); 114 | 115 | 116 | //hijack the thread 117 | threadContext.Eip = (DWORD)remoteCave; 118 | threadContext.ContextFlags = CONTEXT_CONTROL; 119 | SetThreadContext(thread, &threadContext); 120 | ResumeThread(thread); 121 | 122 | //clean 123 | CloseHandle(thread); 124 | } 125 | 126 | DWORD WINAPI hijackThread(LPVOID lpParam) 127 | { 128 | injectCodeUsingThreadHijacking((HANDLE)lpParam, &printStringManyTimes, 2, "hijacked\n"); 129 | return 1; 130 | } 131 | 132 | 133 | void LoadDll(HANDLE process, const wchar_t* dllPath) 134 | { 135 | // write the dll name to memory 136 | int namelen = wcslen(dllPath) + 1; 137 | LPVOID remoteString = VirtualAllocEx(process, NULL, namelen * 2, MEM_COMMIT, PAGE_EXECUTE); 138 | WriteProcessMemory(process, remoteString, dllPath, namelen * 2, NULL); 139 | 140 | // get the address of LoadLibraryW() 141 | HMODULE k32 = GetModuleHandleA("kernel32.dll"); 142 | LPVOID funcAdr = GetProcAddress(k32, "LoadLibraryW"); 143 | 144 | // create the thread 145 | HANDLE thread = 146 | CreateRemoteThread(process, NULL, NULL, (LPTHREAD_START_ROUTINE)funcAdr, remoteString, NULL, NULL); 147 | 148 | // let the thread finish and clean up 149 | WaitForSingleObject(thread, INFINITE); 150 | CloseHandle(thread); 151 | } 152 | 153 | int main(void) 154 | { 155 | HANDLE proc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, GetCurrentProcessId()); 156 | 157 | // inject code into self using thread injection 158 | injectCodeUsingThreadInjection(proc, &printStringManyTimes, 2, "injected\n"); 159 | 160 | // inject code into self using thread hijacking 161 | // we need to do it from a secondary thread or else 162 | // the hijacking code would hijack itself.. which 163 | // doesn't work 164 | CreateThread(NULL, 0, hijackThread, proc, 0, NULL); 165 | 166 | LoadDll(proc, L"Chapter7_CodeInjection_DLL.dll"); 167 | 168 | 169 | while (true) // stay busy 170 | { 171 | Sleep(100); 172 | } 173 | } 174 | -------------------------------------------------------------------------------- /Chapter7_CodeInjection_DLL/Chapter7_CodeInjection_DLL.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | 15 | 16 | 17 | {37305F21-BB4B-4492-A713-DDD94653C16E} 18 | Win32Proj 19 | Chapter7_CodeInjection_DLL 20 | 21 | 22 | 23 | DynamicLibrary 24 | true 25 | Unicode 26 | 27 | 28 | DynamicLibrary 29 | false 30 | true 31 | Unicode 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | true 45 | $(SolutionDir)\BuildTemp\$(ProjectName)_$(Configuration)\ 46 | $(SolutionDir)\bin\DEBUG_BUILDS\ 47 | 48 | 49 | false 50 | $(SolutionDir)\BuildTemp\$(ProjectName)_$(Configuration)\ 51 | $(SolutionDir)\bin\ 52 | 53 | 54 | 55 | NotUsing 56 | Level3 57 | Disabled 58 | WIN32;_DEBUG;_WINDOWS;_USRDLL;CHAPTER7_CODEINJECTION_DLL_EXPORTS;%(PreprocessorDefinitions) 59 | 60 | 61 | Windows 62 | true 63 | 64 | 65 | 66 | 67 | Level3 68 | NotUsing 69 | MaxSpeed 70 | true 71 | true 72 | WIN32;NDEBUG;_WINDOWS;_USRDLL;CHAPTER7_CODEINJECTION_DLL_EXPORTS;%(PreprocessorDefinitions) 73 | 74 | 75 | Windows 76 | true 77 | true 78 | true 79 | 80 | 81 | 82 | 83 | 84 | -------------------------------------------------------------------------------- /Chapter7_CodeInjection_DLL/Chapter7_CodeInjection_DLL.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /Chapter7_CodeInjection_DLL/dllmain.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | 4 | DWORD WINAPI runBot(LPVOID lpParam) { 5 | // run your bot 6 | return 1; 7 | } 8 | 9 | 10 | BOOL APIENTRY DllMain( HMODULE hModule, 11 | DWORD ul_reason_for_call, 12 | LPVOID lpReserved 13 | ) 14 | { 15 | switch (ul_reason_for_call) 16 | { 17 | case DLL_PROCESS_ATTACH: 18 | MessageBoxA(NULL, "DLL Attached!\n", "Game Hacking", MB_OK | MB_TOPMOST); 19 | CreateThread(NULL, 0, &runBot, NULL, 0, NULL); 20 | break; 21 | } 22 | return TRUE; 23 | } -------------------------------------------------------------------------------- /Chapter8_AdobeAirHook/AdobeAirHook.cpp: -------------------------------------------------------------------------------- 1 | #include "AdobeAirHook.h" 2 | #include "AdobeAirHookCallbacks.h" 3 | #include "ExecutableModule.h" 4 | #include "DebugConsole.h" 5 | #include "ThreadLock.h" 6 | 7 | 8 | AdobeAirHook* AdobeAirHook::instance = NULL; 9 | 10 | const char encodePattern[16] = {0x8B, 0xCE, 0xE8, 0xA6, 0xFF, 0xFF, 0xFF, 0x83, 0xF8, 0xFF, 0x74, 0x16, 0x03, 0xF8, 0x3B, 0xBE}; 11 | const char decodePattern[12] = {0x8B, 0xCE, 0xE8, 0x7F, 0xF7, 0xFF, 0xFF, 0x83, 0xF8, 0xFF, 0x89, 0x86}; 12 | 13 | 14 | AdobeAirHook::AdobeAirHook() 15 | { 16 | this->airModule = new ExecutableModule(L"Adobe AIR.dll"); 17 | this->socketLock = new ThreadLock(); 18 | 19 | this->socketLock->enter(); 20 | this->socketLock->leave(); 21 | } 22 | AdobeAirHook::~AdobeAirHook() 23 | { 24 | this->socketLock->enter(); 25 | this->socketLock->leave(); 26 | 27 | delete this->airModule; 28 | delete this->socketLock; 29 | } 30 | 31 | void AdobeAirHook::execute() 32 | { 33 | DebugConsole::getInstance(); 34 | do 35 | { 36 | if (!this->airModule->isValid()) 37 | { 38 | printf("invalid module!\n"); 39 | break; 40 | } 41 | 42 | DWORD encodeAddress = this->airModule->findPattern(encodePattern, 16); 43 | DWORD decodeAddress = this->airModule->findPattern(decodePattern, 12); 44 | if (!encodeAddress || !decodeAddress) 45 | { 46 | printf("invalid encode/decode address!\n"); 47 | break; 48 | } 49 | 50 | encodeAddress += 2; decodeAddress += 2; //call is 2 bytes past start of each pattern 51 | 52 | encodeHookFunction = this->airModule->addCallHook("encode", encodeAddress, &myEncode); 53 | if (!encodeHookFunction) 54 | { 55 | printf("encode hook failed!\n"); 56 | break; 57 | } 58 | 59 | decodeHookFunction = this->airModule->addCallHook("decode", decodeAddress, &myDecode); 60 | if (!encodeHookFunction) 61 | { 62 | printf("encode hook failed!\n"); 63 | break; 64 | } 65 | 66 | printf("hooks installed!\n"); 67 | return; //success 68 | } while (0); 69 | 70 | //error is here 71 | this->terminate(); 72 | } 73 | void AdobeAirHook::terminate() 74 | { 75 | this->airModule->clearCallHooks(); 76 | DebugConsole::deleteInstance(); 77 | } 78 | 79 | DWORD AdobeAirHook::getEncodeHookFunction() 80 | { 81 | return this->encodeHookFunction; 82 | } 83 | 84 | DWORD AdobeAirHook::getDecodeHookFunction() 85 | { 86 | return this->decodeHookFunction; 87 | } 88 | 89 | void AdobeAirHook::encodeHookCallback(const unsigned char* buffer, unsigned int size) 90 | { 91 | if (size == 0xFFFFFFFF) return; 92 | 93 | this->socketLock->enter(); 94 | DebugConsole::getInstance()->dumpBuffer(buffer, size, "Outgoing packet collected"); 95 | this->socketLock->leave(); 96 | } 97 | 98 | void AdobeAirHook::decodeHookCallback(const unsigned char* buffer, unsigned int size) 99 | { 100 | if (size == 0xFFFFFFFF) return; 101 | 102 | this->socketLock->enter(); 103 | DebugConsole::getInstance()->dumpBuffer(buffer, size, "Incoming packet collected"); 104 | this->socketLock->leave(); 105 | } 106 | -------------------------------------------------------------------------------- /Chapter8_AdobeAirHook/AdobeAirHook.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | class ExecutableModule; 5 | class ThreadLock; 6 | class PacketCollector; 7 | 8 | class AdobeAirHook 9 | { 10 | public: 11 | static AdobeAirHook* getInstance() 12 | { 13 | if (!AdobeAirHook::instance) 14 | AdobeAirHook::instance = new AdobeAirHook(); 15 | return AdobeAirHook::instance; 16 | } 17 | static void deleteInstance() 18 | { 19 | if (AdobeAirHook::instance) 20 | { 21 | delete AdobeAirHook::instance; 22 | AdobeAirHook::instance = NULL; 23 | } 24 | } 25 | 26 | void execute(); 27 | void terminate(); 28 | 29 | DWORD getEncodeHookFunction(); 30 | DWORD getDecodeHookFunction(); 31 | void encodeHookCallback(const unsigned char* buffer, unsigned int size); 32 | void decodeHookCallback(const unsigned char* buffer, unsigned int size); 33 | 34 | private: 35 | AdobeAirHook(); 36 | ~AdobeAirHook(); 37 | 38 | static AdobeAirHook* instance; 39 | 40 | ExecutableModule* airModule; 41 | ThreadLock* socketLock; 42 | 43 | DWORD encodeHookFunction, decodeHookFunction; 44 | }; -------------------------------------------------------------------------------- /Chapter8_AdobeAirHook/AdobeAirHook.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {D041E046-6A67-413E-869B-14E3CE06A21B} 15 | Win32Proj 16 | Chapter8_AdobeAirHook 17 | Chapter8_AdobeAirHook 18 | 19 | 20 | 21 | DynamicLibrary 22 | true 23 | Unicode 24 | 25 | 26 | DynamicLibrary 27 | false 28 | true 29 | Unicode 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | true 43 | $(SolutionDir)\BuildTemp\$(ProjectName)_$(Configuration)\ 44 | $(SolutionDir)\bin\DEBUG_BUILDS\ 45 | 46 | 47 | false 48 | $(SolutionDir)\BuildTemp\$(ProjectName)_$(Configuration)\ 49 | $(SolutionDir)\bin\ 50 | 51 | 52 | 53 | NotUsing 54 | Level3 55 | Disabled 56 | WIN32;_DEBUG;_WINDOWS;_USRDLL;ADOBEAIRHOOK_EXPORTS;%(PreprocessorDefinitions) 57 | 58 | 59 | Windows 60 | true 61 | 62 | 63 | 64 | 65 | Level3 66 | NotUsing 67 | MaxSpeed 68 | true 69 | true 70 | WIN32;NDEBUG;_WINDOWS;_USRDLL;ADOBEAIRHOOK_EXPORTS;%(PreprocessorDefinitions) 71 | 72 | 73 | Windows 74 | true 75 | true 76 | true 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | false 91 | 92 | 93 | false 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /Chapter8_AdobeAirHook/AdobeAirHook.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | {ec0c29ac-a76b-41e3-a066-77cd77437405} 18 | 19 | 20 | {e2f43ad2-b882-46d5-ad16-5f30255ba5b5} 21 | 22 | 23 | {1a0cd66b-65d6-498a-92a4-8dcf66820d1a} 24 | 25 | 26 | {93221b58-954d-43c9-bdf5-2f94f2022512} 27 | 28 | 29 | 30 | 31 | Header Files\Utils 32 | 33 | 34 | Header Files\Utils 35 | 36 | 37 | Header Files\Core 38 | 39 | 40 | Header Files\Core 41 | 42 | 43 | Header Files\Core 44 | 45 | 46 | 47 | 48 | Source Files 49 | 50 | 51 | Source Files\Utils 52 | 53 | 54 | Source Files\Core 55 | 56 | 57 | Source Files\Core 58 | 59 | 60 | Source Files 61 | 62 | 63 | -------------------------------------------------------------------------------- /Chapter8_AdobeAirHook/AdobeAirHookCallbacks.h: -------------------------------------------------------------------------------- 1 | #include "AdobeAirHook.h" 2 | #include 3 | #include 4 | 5 | 6 | DWORD __stdcall reportEncode(const unsigned char* buffer, unsigned int size, unsigned int loopCounter) 7 | { 8 | if (loopCounter == 0) 9 | AdobeAirHook::getInstance()->encodeHookCallback(buffer, size); 10 | return AdobeAirHook::getInstance()->getEncodeHookFunction(); 11 | } 12 | 13 | DWORD __stdcall getDecode() 14 | { 15 | return AdobeAirHook::getInstance()->getDecodeHookFunction(); 16 | } 17 | void __stdcall reportDecode(const unsigned char* buffer, unsigned int size) 18 | { 19 | AdobeAirHook::getInstance()->decodeHookCallback(buffer, size); 20 | } 21 | 22 | void __declspec(naked) myEncode() 23 | { 24 | __asm 25 | { 26 | MOV EAX, DWORD PTR SS:[ESP + 0x4] // get buffer 27 | MOV EDX, DWORD PTR DS:[ESI + 0x3C58] // get full size 28 | 29 | PUSH ECX // store ecx 30 | 31 | PUSH EDI // push current pos 32 | PUSH EDX // push size 33 | PUSH EAX // push buffer 34 | CALL reportEncode // report the encode call 35 | 36 | POP ECX // restore ecx 37 | 38 | JMP EAX // jump to original function (returned by reportEncode) 39 | } 40 | } 41 | 42 | void __declspec(naked) myDecode() 43 | { 44 | __asm 45 | { 46 | MOV EAX, DWORD PTR SS:[ESP + 0x4] // get second arg 47 | MOV EDX, DWORD PTR SS:[ESP + 0x8] // get first arg 48 | 49 | PUSH EDX // re-push first arg ------------------. 50 | PUSH EAX // re-push second arg -----------------| 51 | PUSH ECX // store ecx -----------------------. | 52 | CALL getDecode // get the function to call | | 53 | POP ECX // restore ecx ----------------------' | 54 | CALL EAX // call the original function ---------' 55 | 56 | 57 | MOV EDX, DWORD PTR SS:[ESP + 0x4] // get first arg, its the buffer now 58 | 59 | PUSH EAX // store eax ----------------------------. 60 | PUSH ECX // store ecx --------------------------. | 61 | PUSH EAX // push the size -------------------. | | 62 | PUSH EDX // push the buffer -----------------| | | 63 | CALL reportDecode // report the results now -' | | 64 | POP ECX // restore ecx -------------------------' | 65 | POP EAX // restore eax ---------------------------' 66 | RETN 8 // return 67 | } 68 | } -------------------------------------------------------------------------------- /Chapter8_AdobeAirHook/DebugConsole.cpp: -------------------------------------------------------------------------------- 1 | #include "DebugConsole.h" 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | DebugConsole* DebugConsole::instance = NULL;; 9 | 10 | DebugConsole::DebugConsole() 11 | { 12 | this->show(); 13 | } 14 | DebugConsole::~DebugConsole() 15 | { 16 | this->hide(); 17 | } 18 | 19 | void DebugConsole::show() 20 | { 21 | using namespace std; 22 | 23 | auto out = freopen("C:\\leaguelog.txt","w",stdout); 24 | 25 | return; 26 | 27 | static const WORD MAX_CONSOLE_LINES = 5000; 28 | 29 | int hConHandle; 30 | long lStdHandle; 31 | CONSOLE_SCREEN_BUFFER_INFO coninfo; 32 | FILE *fp; 33 | 34 | // allocate a console for this app 35 | AllocConsole(); 36 | 37 | // set the screen buffer to be big enough to let us scroll text 38 | GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &coninfo); 39 | coninfo.dwSize.Y = MAX_CONSOLE_LINES; 40 | SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coninfo.dwSize); 41 | 42 | // redirect unbuffered STDOUT to the console 43 | lStdHandle = (long)GetStdHandle(STD_OUTPUT_HANDLE); 44 | hConHandle = _open_osfhandle(lStdHandle, _O_TEXT); 45 | fp = _fdopen( hConHandle, "w" ); 46 | *stdout = *fp; 47 | setvbuf( stdout, NULL, _IONBF, 0 ); 48 | 49 | // redirect unbuffered STDIN to the console 50 | lStdHandle = (long)GetStdHandle(STD_INPUT_HANDLE); 51 | hConHandle = _open_osfhandle(lStdHandle, _O_TEXT); 52 | fp = _fdopen( hConHandle, "r" ); 53 | *stdin = *fp; 54 | setvbuf( stdin, NULL, _IONBF, 0 ); 55 | 56 | // redirect unbuffered STDERR to the console 57 | lStdHandle = (long)GetStdHandle(STD_ERROR_HANDLE); 58 | hConHandle = _open_osfhandle(lStdHandle, _O_TEXT); 59 | fp = _fdopen( hConHandle, "w" ); 60 | *stderr = *fp; 61 | setvbuf( stderr, NULL, _IONBF, 0 ); 62 | 63 | // make cout, wcout, cin, wcin, wcerr, cerr, wclog and clog 64 | // point to console as well 65 | ios::sync_with_stdio(); 66 | } 67 | void DebugConsole::hide() 68 | { 69 | FreeConsole(); 70 | } 71 | 72 | void DebugConsole::dumpBuffer(const char* buffer, unsigned int size, const char* title) 73 | { 74 | printf("%s> %d bytes", title, size); 75 | 76 | for (unsigned int o = 0; o < ceil(size / 16.0f); o++) 77 | { 78 | printf("\n "); 79 | for (unsigned int t = 0; t < 2; t++) 80 | { 81 | for (unsigned int i = 0; i < 16; i++) 82 | { 83 | unsigned char val = buffer[(o * 16) + i] & 0xFF; 84 | if (t == 0) 85 | { 86 | if (i == 8) 87 | printf("| "); 88 | 89 | if ((o * 16) + i < size) 90 | printf("%02X ", val); 91 | else 92 | printf(" ", val); 93 | } 94 | else if ((o * 16) + i < size) 95 | { 96 | if (val > ' ' && val <= '~') 97 | printf("%c", val); 98 | else 99 | printf("."); 100 | } 101 | else 102 | printf(" "); 103 | } 104 | printf("|"); 105 | } 106 | } 107 | 108 | printf("\n"); 109 | } -------------------------------------------------------------------------------- /Chapter8_AdobeAirHook/DebugConsole.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | #ifdef _DEBUG 6 | #define LOG(message) printf("%s (%d): %s\n", __FUNCTION__, __LINE__, message) 7 | #else 8 | #define LOG(message) 9 | #endif 10 | 11 | class DebugConsole 12 | { 13 | public: 14 | static DebugConsole* getInstance() 15 | { 16 | if (!DebugConsole::instance) 17 | DebugConsole::instance = new DebugConsole(); 18 | return DebugConsole::instance; 19 | } 20 | static void deleteInstance() 21 | { 22 | if (DebugConsole::instance) 23 | { 24 | delete DebugConsole::instance; 25 | DebugConsole::instance = NULL; 26 | } 27 | } 28 | void dumpBuffer(const char* buffer, unsigned int size, const char* title); 29 | void dumpBuffer(char* buffer, unsigned int size, const char* title) { this->dumpBuffer((const char*)buffer, size, title); } 30 | void dumpBuffer(unsigned char* buffer, unsigned int size, const char* title) { this->dumpBuffer((const char*)buffer, size, title); } 31 | void dumpBuffer(const unsigned char* buffer, unsigned int size, const char* title) { this->dumpBuffer((const char*)buffer, size, title); } 32 | 33 | private: 34 | static DebugConsole* instance; 35 | 36 | DebugConsole(); 37 | ~DebugConsole(); 38 | 39 | void show(); 40 | void hide(); 41 | }; -------------------------------------------------------------------------------- /Chapter8_AdobeAirHook/ExecutableModule.cpp: -------------------------------------------------------------------------------- 1 | #include "ExecutableModule.h" 2 | 3 | #include 4 | #include 5 | 6 | 7 | ExecutableModule::ExecutableModule(const wchar_t* moduleName) : name(moduleName), base(0), size(0), oldProtect(0) 8 | { 9 | this->getModuleInformation(); 10 | } 11 | 12 | 13 | ExecutableModule::~ExecutableModule(void) 14 | { 15 | } 16 | 17 | DWORD ExecutableModule::findPattern(const char* pattern, unsigned int patternLength, unsigned int occurance) 18 | { 19 | unsigned int ocur = 0; 20 | for (DWORD adr = this->base; adr <= this->base + this->size - patternLength; adr++) 21 | { 22 | 23 | if (memcmp((LPVOID)pattern, (LPVOID)adr, patternLength) == 0) 24 | { 25 | ocur++; 26 | if (ocur == occurance) 27 | return adr; 28 | } 29 | } 30 | return 0; 31 | } 32 | 33 | DWORD ExecutableModule::addCallHook(const char* name, DWORD address, LPVOID function) 34 | { 35 | callHookInformation hook; 36 | hook.hookAtAddress = address; 37 | hook.newFuncAddress = (DWORD)function; 38 | 39 | if (this->readMemory(hook.hookAtAddress) != 0xE8) 40 | { 41 | printf("Hook %s is not on a valid opcode (saw 0x%02x at address 0x%08x)!\n", 42 | name, 43 | this->readMemory(hook.hookAtAddress), 44 | hook.hookAtAddress); 45 | return 0; 46 | } 47 | 48 | bool hooked = true; 49 | this->allowOPCodeModification(hook.hookAtAddress + 1, 4); 50 | { 51 | hook.oldFuncOffset = this->readMemory(hook.hookAtAddress + 1); 52 | if (!this->writeMemory(hook.hookAtAddress + 1, hook.newFuncAddress - hook.hookAtAddress - 5)) 53 | { 54 | printf("Failed to write memory for hook %s!\n", name); 55 | hooked = false; 56 | } 57 | } 58 | this->disallowOPCodeModification(hook.hookAtAddress + 1, 4); 59 | 60 | if (!hooked) 61 | return 0; 62 | 63 | this->callHooks.push_back(hook); 64 | return hook.getOldFunctionAddress(); 65 | } 66 | 67 | void ExecutableModule::clearCallHooks() 68 | { 69 | for (auto hook = this->callHooks.begin(); hook != this->callHooks.end(); hook++) 70 | { 71 | this->allowOPCodeModification(hook->hookAtAddress + 1, 4); 72 | this->writeMemory(hook->hookAtAddress + 1, hook->oldFuncOffset); 73 | this->disallowOPCodeModification(hook->hookAtAddress + 1, 4); 74 | } 75 | this->callHooks.clear(); 76 | } 77 | 78 | void ExecutableModule::getModuleInformation() 79 | { 80 | MODULEENTRY32 entry; 81 | entry.dwSize = sizeof(MODULEENTRY32); 82 | 83 | HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, NULL); 84 | 85 | if (Module32First(snapshot, &entry) == TRUE) 86 | { 87 | while (Module32Next(snapshot, &entry) == TRUE) 88 | { 89 | std::wstring binaryPath = entry.szModule; 90 | if (binaryPath.find(this->name) != std::wstring::npos) 91 | { 92 | this->size = (DWORD)entry.modBaseSize; 93 | this->base = (DWORD)entry.modBaseAddr; 94 | break; 95 | } 96 | } 97 | } 98 | 99 | CloseHandle(snapshot); 100 | } 101 | 102 | 103 | void ExecutableModule::allowOPCodeModification(DWORD address, unsigned int size) 104 | { 105 | this->oldProtect = this->setRegionProtection(address, size, PAGE_EXECUTE_READWRITE); 106 | } 107 | void ExecutableModule::disallowOPCodeModification(DWORD address, unsigned int size) 108 | { 109 | this->setRegionProtection(address, size, (oldProtect) ? oldProtect : PAGE_WRITECOPY); 110 | } 111 | DWORD ExecutableModule::setRegionProtection(DWORD address, unsigned int size, DWORD protection) 112 | { 113 | DWORD oldProtection; 114 | VirtualProtect((LPVOID)address, size, protection, &oldProtection); 115 | return oldProtection; 116 | } -------------------------------------------------------------------------------- /Chapter8_AdobeAirHook/ExecutableModule.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | 5 | class ExecutableModule 6 | { 7 | public: 8 | ExecutableModule(const wchar_t* moduleName); 9 | ~ExecutableModule(); 10 | 11 | DWORD findPattern(const char* pattern, unsigned int patternLength, unsigned int occurance = 1); 12 | DWORD addCallHook(const char* name, DWORD address, LPVOID function); 13 | void clearCallHooks(); 14 | 15 | bool isValid() { return this->base > 0 && this->size > 0; } 16 | 17 | DWORD getBase() { return this->base; } 18 | DWORD getSize() { return this->size; } 19 | 20 | template 21 | T* pointMemory(DWORD address) 22 | { 23 | return (T*)address; 24 | } 25 | 26 | template 27 | T readMemory(DWORD address) 28 | { 29 | if (address < this->base || address > (this->base + this->size)) 30 | { 31 | T ret; 32 | memset(&ret, 0, sizeof(T)); 33 | return ret; 34 | } 35 | return *(T*)address; 36 | } 37 | 38 | template 39 | bool writeMemory(DWORD address, T value) 40 | { 41 | if (address < this->base || address > (this->base + this->size)) 42 | return false; 43 | *(T*)(address) = value; 44 | return true; 45 | } 46 | 47 | private: 48 | struct callHookInformation 49 | { 50 | const char* name; 51 | DWORD hookAtAddress; 52 | DWORD newFuncAddress; 53 | DWORD oldFuncOffset; 54 | 55 | DWORD getOldFunctionAddress() 56 | { 57 | return hookAtAddress + oldFuncOffset + 5; 58 | } 59 | }; 60 | 61 | const wchar_t* name; 62 | DWORD base, size, oldProtect; 63 | std::list callHooks; 64 | 65 | void getModuleInformation(); 66 | 67 | void allowOPCodeModification(DWORD address, unsigned int size); 68 | void disallowOPCodeModification(DWORD address, unsigned int size); 69 | DWORD setRegionProtection(DWORD address, unsigned int size, DWORD protection); 70 | }; 71 | 72 | -------------------------------------------------------------------------------- /Chapter8_AdobeAirHook/ThreadLock.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | class ThreadLock 5 | { 6 | public: 7 | ThreadLock() 8 | { 9 | InitializeCriticalSection(&cs); 10 | } 11 | 12 | ~ThreadLock(){ 13 | DeleteCriticalSection(&cs); 14 | } 15 | 16 | void enter() 17 | { 18 | EnterCriticalSection(&cs); 19 | } 20 | 21 | void leave() 22 | { 23 | LeaveCriticalSection(&cs); 24 | } 25 | private: 26 | CRITICAL_SECTION cs; 27 | }; -------------------------------------------------------------------------------- /Chapter8_AdobeAirHook/dllmain.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include "AdobeAirHook.h" 3 | AdobeAirHook* hook; 4 | 5 | BOOL APIENTRY DllMain( HMODULE hModule, 6 | DWORD ul_reason_for_call, 7 | LPVOID lpReserved 8 | ) 9 | { 10 | switch (ul_reason_for_call) 11 | { 12 | case DLL_PROCESS_ATTACH: 13 | AdobeAirHook::getInstance()->execute(); 14 | break; 15 | case DLL_PROCESS_DETACH: 16 | AdobeAirHook::getInstance()->terminate(); 17 | AdobeAirHook::deleteInstance(); 18 | break; 19 | case DLL_THREAD_ATTACH: 20 | case DLL_THREAD_DETACH: 21 | break; 22 | } 23 | return TRUE; 24 | } 25 | 26 | -------------------------------------------------------------------------------- /Chapter8_ControlFlow/CallHookExample.cpp: -------------------------------------------------------------------------------- 1 | #include "main.h" 2 | 3 | // the function thaat we're going to hook 4 | DWORD functionToBeHooked(DWORD arg1, DWORD arg2, DWORD arg3) 5 | { 6 | if (arg1 == arg2 && arg2 == 3 && arg3 == 4) 7 | printf("Call hook worked! Parameters intercepted and changed!\n"); 8 | else 9 | printf("Call hook failed!\n"); 10 | return 0; 11 | } 12 | 13 | // the hook will replace the call in this function 14 | // to call our hook 15 | void whereHookGoes() 16 | { 17 | functionToBeHooked(0, 0, 0); 18 | } 19 | 20 | // I cannot hard-code any addresses from within this application, 21 | // as they may change upon re-compile. For this reason, I'll locate 22 | // the address of the CALL that I want to replace programatically 23 | // by scanning for the 'CALL' statement (bytes 0xE8) 24 | // somewhere within 1000 bytes of the start of the function 25 | DWORD getAddressForCallHook(DWORD functionStart) 26 | { 27 | auto oldProtection = protectMemory(functionStart, PAGE_EXECUTE_READ); // make sure memory is readable, just incase 28 | auto mem = pointMemory(functionStart); 29 | 30 | DWORD ret = 0; 31 | for (int i = 0; i < 1000; i++) { 32 | if (mem[i] == 0xE8) { 33 | ret = functionStart + i; 34 | break; 35 | } 36 | } 37 | protectMemory(functionStart, oldProtection); // restore old memory protection 38 | return ret; 39 | } 40 | 41 | 42 | // this our our type-def that minmics the function type 43 | // of the function being hooked. This allows us to use a 44 | // clean call to the original function just knowing it's address 45 | typedef DWORD (__cdecl _origFunc)(DWORD arg1, DWORD arg2, DWORD arg3); 46 | _origFunc* originalFunction; 47 | 48 | // this is the function we re-direct the CALL to. 49 | // it simply throws out the orignal parameters 50 | // and passes new ones to the original function 51 | DWORD __cdecl someNewFunction(DWORD arg1, DWORD arg2, DWORD arg3) 52 | { 53 | return originalFunction(3, 3, 4); 54 | } 55 | 56 | // this function is what actually places the hook 57 | DWORD callHook(DWORD hookAt, DWORD newFunc) 58 | { 59 | DWORD newOffset = newFunc - hookAt - 5; 60 | 61 | auto oldProtection = protectMemory(hookAt + 1, PAGE_EXECUTE_READWRITE); 62 | 63 | DWORD originalOffset = readMemory(hookAt + 1); 64 | writeMemory(hookAt + 1, newOffset); 65 | protectMemory(hookAt + 1, oldProtection); 66 | 67 | return originalOffset + hookAt + 5; 68 | } 69 | 70 | // This ties the entire example together 71 | void callHookExample() 72 | { 73 | auto address = getAddressForCallHook((DWORD)&whereHookGoes); 74 | if (address) 75 | originalFunction = (_origFunc*)callHook(address, (DWORD)&someNewFunction); 76 | 77 | whereHookGoes(); 78 | } -------------------------------------------------------------------------------- /Chapter8_ControlFlow/Chapter8_ControlFlow.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {ACA1A8FF-6D8C-407A-983C-929D6F958D83} 15 | Win32Proj 16 | Chapter8_ControlFlow 17 | Chapter8_ControlFlow 18 | 19 | 20 | 21 | Application 22 | true 23 | Unicode 24 | 25 | 26 | Application 27 | false 28 | true 29 | Unicode 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | true 43 | $(SolutionDir)\BuildTemp\$(ProjectName)_$(Configuration)\ 44 | $(SolutionDir)\bin\DEBUG_BUILDS\ 45 | 46 | 47 | false 48 | $(SolutionDir)\BuildTemp\$(ProjectName)_$(Configuration)\ 49 | $(SolutionDir)\bin\ 50 | 51 | 52 | 53 | 54 | 55 | Level3 56 | Disabled 57 | WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) 58 | 4Bytes 59 | 60 | 61 | Console 62 | true 63 | false 64 | 65 | 66 | 67 | 68 | Level3 69 | 70 | 71 | Disabled 72 | true 73 | true 74 | WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 75 | 4Bytes 76 | 77 | 78 | Console 79 | true 80 | true 81 | true 82 | 83 | 84 | false 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | -------------------------------------------------------------------------------- /Chapter8_ControlFlow/Chapter8_ControlFlow.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Source Files 6 | 7 | 8 | Source Files 9 | 10 | 11 | Source Files 12 | 13 | 14 | Source Files 15 | 16 | 17 | Source Files 18 | 19 | 20 | 21 | 22 | {1ccf619e-78d1-4364-adcb-e255c0253713} 23 | 24 | 25 | {00f1f1a3-3e5e-4f2c-8cbb-285f328f13d1} 26 | 27 | 28 | 29 | 30 | Header Files 31 | 32 | 33 | -------------------------------------------------------------------------------- /Chapter8_ControlFlow/IATHookExample.cpp: -------------------------------------------------------------------------------- 1 | #include "main.h" 2 | 3 | // this is the function that scans the import table and 4 | // overwrites the target function address with our hook 5 | // destination address 6 | DWORD hookIAT(const char* functionName, DWORD newFunctionAddress) 7 | { 8 | DWORD baseAddress = (DWORD)GetModuleHandle(NULL); 9 | 10 | auto dosHeader = pointMemory(baseAddress); 11 | if (dosHeader->e_magic != 0x5A4D) 12 | return 0; 13 | 14 | auto optHeader = pointMemory(baseAddress + dosHeader->e_lfanew + 24); 15 | if (optHeader->Magic != 0x10B) 16 | return 0; 17 | 18 | if (optHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size == 0 || 19 | optHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress == 0) 20 | return 0; 21 | 22 | IMAGE_IMPORT_DESCRIPTOR* importDescriptor = pointMemory(baseAddress + optHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress); //what is the rule of adding them? 23 | while (importDescriptor->FirstThunk) 24 | { 25 | int n = 0; 26 | IMAGE_THUNK_DATA* thunkData = pointMemory(baseAddress + importDescriptor->OriginalFirstThunk); 27 | while (thunkData->u1.Function) 28 | { 29 | char* importFunctionName = pointMemory(baseAddress + (DWORD)thunkData->u1.AddressOfData + 2); 30 | if (strcmp(importFunctionName, functionName) == 0) 31 | { 32 | auto vfTable = pointMemory(baseAddress + importDescriptor->FirstThunk); 33 | 34 | DWORD original = vfTable[n]; 35 | 36 | auto oldProtection = protectMemory((DWORD)&vfTable[n], PAGE_READWRITE); 37 | vfTable[n] = newFunctionAddress; 38 | protectMemory((DWORD)&vfTable[n], oldProtection); 39 | 40 | return original; 41 | } 42 | 43 | n++; 44 | thunkData++; 45 | } 46 | importDescriptor++; 47 | } 48 | 49 | return 0; 50 | } 51 | 52 | // this our our type-def that minmics the function type 53 | // of the function being hooked. This allows us to use a 54 | // clean call to the original function just knowing it's address 55 | typedef VOID (WINAPI _origSleep)(DWORD ms); 56 | _origSleep* originalSleep; 57 | 58 | // this is the function we re-direct any Sleep() call to. 59 | // it simply denies all Sleep calls that last for more than 60 | // 100 miliseconds, printing some text upon success 61 | VOID WINAPI newSleepFunction(DWORD ms) 62 | { 63 | if (ms > 100) 64 | printf("Sleep hook worked! Denied sleep for %d miliseconds.\n", ms); 65 | else 66 | originalSleep(ms); 67 | } 68 | 69 | // This is the function that ties everything together 70 | void IATHookExample() 71 | { 72 | originalSleep = (_origSleep*)hookIAT("Sleep", (DWORD)&newSleepFunction); 73 | Sleep(1234); 74 | } -------------------------------------------------------------------------------- /Chapter8_ControlFlow/NOPExample.cpp: -------------------------------------------------------------------------------- 1 | #include "main.h" 2 | 3 | // this is the simulated list of creatures in the game 4 | std::vector<_creature> creatures; 5 | int creaturesDrawn = 0; 6 | 7 | // this is the simulated function to draw creature names 8 | void drawHealthBar(int healthbar) 9 | { 10 | creaturesDrawn++; // make a note that we drew it 11 | Sleep(healthbar); // just an example, we're not really doing anything 12 | } 13 | 14 | // this is the function where we place the NOP. 15 | void drawCreatureHealthBarExample() 16 | { 17 | for (int i = 0; i < creatures.size(); i++) { 18 | auto c = creatures[i]; 19 | if (c.isEnemy && c.isCloaked) 20 | { 21 | // our NOP is esentially going to remove this continue statement, 22 | // which will be a JUMP that evades the drawHealthBar car 23 | continue; 24 | } 25 | drawHealthBar(c.healthBar); 26 | } 27 | } 28 | 29 | // this is the function that actually does the NOP 30 | template 31 | void writeNop(DWORD address) 32 | { 33 | auto oldProtection = protectMemory(address, PAGE_EXECUTE_READWRITE); 34 | for (int i = 0; i < SIZE; i++) 35 | writeMemory(address + i, 0x90); 36 | protectMemory(address, oldProtection); 37 | } 38 | 39 | 40 | // I cannot hard-code any addresses from within this application, 41 | // as they may change upon re-compile. For this reason, I'll locate 42 | // the address of the JMP that I want to replace programatically 43 | // by scanning for the 'JMP -67' statement (bytes 0xEB 0xBD) 44 | // somewhere within 1000 bytes of the start of the function 45 | DWORD getAddressForNOP(DWORD functionStart) 46 | { 47 | auto oldProtection = protectMemory(functionStart, PAGE_EXECUTE_READ); // make sure memory is readable, just incase 48 | auto mem = pointMemory(functionStart); 49 | 50 | DWORD ret = 0; 51 | for (int i = 0; i < 999; i++) { 52 | if (mem[i] == 0xEB && mem[i+1] == 0xBD) { 53 | ret = functionStart + i; 54 | break; 55 | } 56 | } 57 | protectMemory(functionStart, oldProtection); // restore old memory protection 58 | return ret; 59 | } 60 | 61 | // This ties the entire example together 62 | void NOPExample() 63 | { 64 | creaturesDrawn = 0; 65 | 66 | // nop it 67 | auto address = getAddressForNOP((DWORD)&drawCreatureHealthBarExample); 68 | if (address) 69 | writeNop<2>(address); 70 | 71 | // add some make creatures 72 | creatures.push_back(_creature(0, true, true)); 73 | creatures.push_back(_creature(0, true, false)); 74 | creatures.push_back(_creature(0, false, true)); 75 | creatures.push_back(_creature(0, false, false)); 76 | 77 | //call the function 78 | drawCreatureHealthBarExample(); 79 | 80 | //check if NOP worked 81 | if (creaturesDrawn == 4) 82 | printf("NOP worked! Drew all creatures!\n"); 83 | else 84 | printf("NOP failed! :( Only drew %d/4 creatures.\n", creaturesDrawn); 85 | } -------------------------------------------------------------------------------- /Chapter8_ControlFlow/VFHookExample.cpp: -------------------------------------------------------------------------------- 1 | #include "main.h" 2 | 3 | // This is a dummy base-class 4 | class someBaseClass 5 | { 6 | public: 7 | virtual DWORD someFunction(DWORD arg1) { return 0; } 8 | }; 9 | 10 | // This is the class for which we'll 11 | // actually hook the VF table. It inherits 12 | // the dummy base-class to ensure that 13 | // someFunction() is in a virtual table. 14 | class someClass : public someBaseClass 15 | { 16 | public: 17 | virtual DWORD someFunction(DWORD arg1) 18 | { 19 | if (arg1 == 1) 20 | printf(" VF Table hook worked! Parameters intercepted and changed!\n"); 21 | else 22 | printf(" VF Table hook failed!\n"); 23 | return 0; 24 | } 25 | }; 26 | 27 | 28 | // This is where we re-direct the VF calls to 29 | DWORD originalVFFunction; 30 | DWORD __stdcall someNewVFFunction(DWORD arg1) 31 | { 32 | // notice how we take ECX and store it in a variable.. 33 | // this is done because it stores the class instance pointer ("this") 34 | // and we want to make sure our code doesn't overwrite it (the compiler 35 | // doesn't understand that this is a VF hook, so it may think ECX is 36 | // free for it to use) 37 | 38 | static DWORD _this, _ret; 39 | __asm MOV _this, ECX 40 | 41 | printf("VFHook pre\n"); 42 | __asm { 43 | PUSH 1 44 | MOV ECX, _this 45 | CALL [originalVFFunction] 46 | MOV _ret, EAX 47 | } 48 | printf("VFHook Post\n"); 49 | 50 | __asm MOV ECX, _this 51 | return _ret; 52 | } 53 | 54 | // This is the function that actually places the hook 55 | DWORD hookVF(DWORD classInst, DWORD funcIndex, DWORD newFunc) 56 | { 57 | DWORD VFTable = readMemory(classInst); 58 | DWORD hookAddress = VFTable + funcIndex * sizeof(DWORD); 59 | 60 | auto oldProtection = protectMemory(hookAddress, PAGE_READWRITE); 61 | DWORD originalFunc = readMemory(hookAddress); 62 | writeMemory(hookAddress, newFunc); 63 | protectMemory(hookAddress, oldProtection); 64 | 65 | return originalFunc; 66 | } 67 | 68 | // This is the function that ties everything together 69 | void VFHookExample() 70 | { 71 | someClass* inst = new someClass(); 72 | 73 | originalVFFunction = hookVF((DWORD)inst, 0, (DWORD)&someNewVFFunction); 74 | inst->someFunction(0); 75 | delete inst; 76 | } -------------------------------------------------------------------------------- /Chapter8_ControlFlow/main-controlFlow.cpp: -------------------------------------------------------------------------------- 1 | #include "main.h" 2 | 3 | int main(void) 4 | { 5 | // due to differences in the way functions are compiled between 6 | // DEBUG and RELEASE builds, this example will only work in RELEASE. 7 | // This is only because of the way I'm finding the addresses of 8 | // the NOP and CALL targets 9 | NOPExample(); 10 | callHookExample(); 11 | VFHookExample(); 12 | IATHookExample(); 13 | 14 | while (true) // stay busy 15 | { 16 | Sleep(100); 17 | } 18 | } -------------------------------------------------------------------------------- /Chapter8_ControlFlow/main.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | /* 6 | THIS IS JUST SOME BOILER-PLATE TO ALLOW THE EXAMPLE CODE TO WORK, 7 | NOTHING INTERESTING HERE 8 | */ 9 | 10 | 11 | template 12 | T readMemory(DWORD address) 13 | { 14 | return *((T*)address); 15 | } 16 | 17 | template 18 | T* pointMemory(DWORD address) 19 | { 20 | return ((T*)address); 21 | } 22 | 23 | template 24 | void writeMemory(DWORD address, T value) 25 | { 26 | *((T*)address) = value; 27 | } 28 | 29 | template 30 | DWORD protectMemory(DWORD address, DWORD prot) 31 | { 32 | DWORD oldProt; 33 | VirtualProtect((LPVOID)address, sizeof(T), prot, &oldProt); 34 | return oldProt; 35 | } 36 | 37 | struct _creature 38 | { 39 | _creature(int hb, bool e, bool c) : healthBar(hb), isEnemy(e), isCloaked(c) {} 40 | int healthBar; 41 | bool isEnemy, isCloaked; 42 | }; 43 | void NOPExample(); 44 | void callHookExample(); 45 | void VFHookExample(); 46 | void IATHookExample(); -------------------------------------------------------------------------------- /Chapter8_Direct3DApplication/Chapter8_Direct3DApplication.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | {E621BD23-8A39-4BA3-9DB0-191661BBF6C9} 15 | Chapter8_Direct3DApplication 16 | 17 | 18 | 19 | Application 20 | true 21 | MultiByte 22 | 23 | 24 | Application 25 | false 26 | true 27 | MultiByte 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | $(SolutionDir)\BuildTemp\$(ProjectName)_$(Configuration)\ 41 | $(SolutionDir)\bin\ 42 | 43 | 44 | $(SolutionDir)\BuildTemp\$(ProjectName)_$(Configuration)\ 45 | $(SolutionDir)\bin\DEBUG_BUILDS\ 46 | 47 | 48 | 49 | Level3 50 | Disabled 51 | 52 | 53 | true 54 | 55 | 56 | 57 | 58 | Level3 59 | MaxSpeed 60 | true 61 | true 62 | 63 | 64 | true 65 | true 66 | true 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /Chapter8_Direct3DApplication/Chapter8_Direct3DApplication.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | -------------------------------------------------------------------------------- /Chapter8_Direct3DHook/Chapter8_Direct3DHook.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Release 10 | Win32 11 | 12 | 13 | 14 | Chapter8_Direct3DHook 15 | {784C482A-F6EC-4BCB-851E-07BE782BB040} 16 | Chapter8_Direct3DHook 17 | Win32Proj 18 | 19 | 20 | 21 | DynamicLibrary 22 | Unicode 23 | true 24 | 25 | 26 | DynamicLibrary 27 | Unicode 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | <_ProjectFileVersion>10.0.40219.1 41 | $(SolutionDir)\bin\DEBUG_BUILDS\ 42 | $(SolutionDir)\BuildTemp\$(ProjectName)_$(Configuration)\ 43 | true 44 | $(SolutionDir)\bin\ 45 | $(SolutionDir)\BuildTemp\$(ProjectName)_$(Configuration)\ 46 | false 47 | $(ExecutablePath) 48 | $(ProjectName) 49 | 50 | 51 | 52 | Disabled 53 | C:\Program Files (x86)\Microsoft DirectX SDK (June 2010)\Include;%(AdditionalIncludeDirectories) 54 | WIN32;_DEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 55 | true 56 | EnableFastChecks 57 | MultiThreadedDebugDLL 58 | 59 | 60 | Level3 61 | EditAndContinue 62 | 63 | 64 | detours.lib;%(AdditionalDependencies) 65 | $(OutDir)$(ProjectName).dll 66 | 67 | 68 | true 69 | Windows 70 | 71 | 72 | MachineX86 73 | 74 | 75 | 76 | 77 | MaxSpeed 78 | true 79 | C:\Program Files (x86)\Microsoft DirectX SDK (June 2010)\Include;%(AdditionalIncludeDirectories) 80 | WIN32;NDEBUG;_WINDOWS;_USRDLL;%(PreprocessorDefinitions) 81 | MultiThreadedDLL 82 | true 83 | 84 | 85 | Level3 86 | ProgramDatabase 87 | 88 | 89 | %(AdditionalDependencies) 90 | $(OutDir)$(ProjectName).dll 91 | 92 | 93 | true 94 | Windows 95 | true 96 | true 97 | 98 | 99 | MachineX86 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | -------------------------------------------------------------------------------- /Chapter8_Direct3DHook/Chapter8_Direct3DHook.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | Source Files 23 | 24 | 25 | 26 | 27 | Header Files 28 | 29 | 30 | Header Files 31 | 32 | 33 | Header Files 34 | 35 | 36 | -------------------------------------------------------------------------------- /Chapter8_Direct3DHook/DirectXHook.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #pragma once 4 | #define WIN32_LEAN_AND_MEAN 5 | 6 | #include 7 | 8 | #include 9 | #pragma comment(lib, "winmm.lib") 10 | #include 11 | #include 12 | 13 | #include 14 | #include 15 | #pragma comment(lib, "d3d9.lib") 16 | #pragma comment(lib, "d3dx9.lib") 17 | 18 | #include 19 | 20 | #define DX_API HRESULT WINAPI 21 | 22 | typedef HRESULT (WINAPI* _reset)(LPDIRECT3DDEVICE9 pDevice, D3DPRESENT_PARAMETERS* pPresentationParameters); 23 | typedef HRESULT (WINAPI* _endScene)(LPDIRECT3DDEVICE9 pDevice); 24 | typedef HRESULT (WINAPI* _drawPrimitive)(LPDIRECT3DDEVICE9 pDevice, D3DPRIMITIVETYPE PrimitiveType, UINT StartVertex, UINT PrimitiveCount); 25 | typedef HRESULT (WINAPI* _drawIndexedPrimitive)(LPDIRECT3DDEVICE9 pDevice, D3DPRIMITIVETYPE PrimType, INT BaseVertexIndex, UINT MinVertexIndex, UINT NumVertices, UINT startIndex, UINT primCount); 26 | 27 | 28 | class DirectXHook; 29 | typedef void (*_drawFrameCallback)(DirectXHook* hook, LPDIRECT3DDEVICE9 pDevice); 30 | typedef void (*_drawPrimitiveCallback)(DirectXHook* hook, LPDIRECT3DDEVICE9 pDevice, D3DPRIMITIVETYPE PrimitiveType, UINT StartVertex, UINT PrimitiveCount); 31 | typedef void (*_drawIndexedPrimitiveCallback)(DirectXHook* hook, LPDIRECT3DDEVICE9 device, D3DPRIMITIVETYPE primType, INT baseVertexIndex, UINT minVertexIndex, UINT numVertices, UINT startIndex, UINT primCount); 32 | 33 | class DirectXHook 34 | { 35 | public: 36 | static _reset origReset; 37 | static _endScene origEndScene; 38 | static _drawPrimitive origDrawPrimitive; 39 | static _drawIndexedPrimitive origDrawIndexedPrimitive; 40 | 41 | static DirectXHook* getInstance() 42 | { 43 | if (!DirectXHook::instance) 44 | DirectXHook::instance = new DirectXHook(); 45 | return DirectXHook::instance; 46 | } 47 | static void deleteInstance() 48 | { 49 | if (DirectXHook::instance) 50 | { 51 | delete DirectXHook::instance; 52 | DirectXHook::instance = NULL; 53 | } 54 | } 55 | void initialize(); 56 | 57 | void addDrawFrameCallback(_drawFrameCallback cb); 58 | void addDrawPrimitiveCallback(_drawPrimitiveCallback cb); 59 | void addDrawIndexedPrimitiveCallback(_drawIndexedPrimitiveCallback cb); 60 | 61 | LPDIRECT3DTEXTURE9 addTexture(std::wstring imagePath); 62 | int addSpriteImage(std::wstring imagePath); 63 | 64 | void drawText(int x, int y, D3DCOLOR color, const char *text, ...); 65 | void drawSpriteImage(int imageID, int x, int y, int w, int h); 66 | 67 | DWORD initHookCallback(LPDIRECT3DDEVICE9 device); 68 | DX_API resetHookCallback(LPDIRECT3DDEVICE9 pDevice, D3DPRESENT_PARAMETERS* pPresentationParameters); 69 | DX_API endSceneHookCallback(LPDIRECT3DDEVICE9 pDevice); 70 | DX_API drawPrimitiveHookCallback(LPDIRECT3DDEVICE9 pDevice, D3DPRIMITIVETYPE PrimitiveType, UINT StartVertex, UINT PrimitiveCount); 71 | DX_API drawIndexedPrimitiveHookCallback(LPDIRECT3DDEVICE9 pDevice, D3DPRIMITIVETYPE PrimType, INT BaseVertexIndex, UINT MinVertexIndex, UINT NumVertices, UINT startIndex, UINT primCount); 72 | 73 | 74 | private: 75 | DirectXHook(void) {}; 76 | ~DirectXHook(void) {}; 77 | 78 | 79 | static DirectXHook* instance; 80 | static unsigned char* originalEndSceneCode; 81 | static DWORD endSceneAddress; 82 | static LPDIRECT3DDEVICE9 hookedDevice; 83 | 84 | static bool hookReadyPre, hookReady; 85 | 86 | std::vector<_drawFrameCallback> drawFrameCallbacks; 87 | std::vector<_drawPrimitiveCallback> drawPrimitiveCallbacks; 88 | std::vector<_drawIndexedPrimitiveCallback> drawIndexedPrimitiveCallbacks; 89 | 90 | std::vector imageBitmaps; 91 | std::vector imageDescriptions; 92 | std::vector imageSprites; 93 | 94 | LPD3DXFONT font; 95 | 96 | void onLostDevice(); 97 | 98 | void placeHooks(); 99 | DWORD locateEndScene(); 100 | 101 | 102 | struct VFHookInfo 103 | { 104 | VFHookInfo(DWORD _index, DWORD cb, DWORD* _origFunc) : index(_index), callback(cb), origFunc(_origFunc) {} 105 | DWORD index, callback; 106 | DWORD* origFunc; 107 | }; 108 | }; 109 | 110 | -------------------------------------------------------------------------------- /Chapter8_Direct3DHook/DirectXHookCallbacks.h: -------------------------------------------------------------------------------- 1 | #include "DirectXHook.h" 2 | 3 | 4 | DWORD __stdcall reportInitEndScene(LPDIRECT3DDEVICE9 discoveredDeviceAddress) 5 | { 6 | return DirectXHook::getInstance()->initHookCallback(discoveredDeviceAddress); 7 | } 8 | __declspec(naked) void endSceneTrampoline() 9 | { 10 | __asm 11 | { 12 | MOV EAX, DWORD PTR SS:[ESP + 0x4] 13 | PUSH EAX 14 | CALL reportInitEndScene 15 | JMP EAX 16 | } 17 | } 18 | 19 | 20 | DX_API myReset(LPDIRECT3DDEVICE9 pDevice, D3DPRESENT_PARAMETERS* pPresentationParameters) 21 | { 22 | return DirectXHook::getInstance()->resetHookCallback(pDevice, pPresentationParameters); 23 | } 24 | 25 | DX_API myEndScene(LPDIRECT3DDEVICE9 pDevice) 26 | { 27 | return DirectXHook::getInstance()->endSceneHookCallback(pDevice); 28 | } 29 | 30 | DX_API myDrawPrimitive(LPDIRECT3DDEVICE9 pDevice, D3DPRIMITIVETYPE PrimitiveType, UINT StartVertex, UINT PrimitiveCount) 31 | { 32 | return DirectXHook::getInstance()->drawPrimitiveHookCallback(pDevice, PrimitiveType, StartVertex, PrimitiveCount); 33 | } 34 | 35 | DX_API myDrawIndexedPrimitive(LPDIRECT3DDEVICE9 pDevice, D3DPRIMITIVETYPE PrimType, INT BaseVertexIndex, UINT MinVertexIndex, UINT NumVertices, UINT startIndex, UINT primCount) 36 | { 37 | return DirectXHook::getInstance()->drawIndexedPrimitiveHookCallback(pDevice, PrimType, BaseVertexIndex, MinVertexIndex, NumVertices, startIndex, primCount); 38 | } -------------------------------------------------------------------------------- /Chapter8_Direct3DHook/main.cpp: -------------------------------------------------------------------------------- 1 | #include "DirectXHook.h" 2 | 3 | int primitivesDrawn = 0; 4 | int gliderImage = 0; 5 | bool initialized = false; 6 | 7 | 8 | ////////////////// CHAPTER 9 LIGTHACK STUFF ////////////////// 9 | bool lightHack = false; 10 | void enableLightHackDirectional(LPDIRECT3DDEVICE9 pDevice) 11 | { 12 | D3DLIGHT9 light; 13 | 14 | ZeroMemory(&light, sizeof(light)); 15 | light.Type = D3DLIGHT_DIRECTIONAL; 16 | light.Diffuse = D3DXCOLOR(0.5f, 0.5f, 0.5f, 1.0f); 17 | light.Direction = D3DXVECTOR3(-1.0f, -0.5f, -1.0f); 18 | 19 | pDevice->SetLight(0, &light); 20 | pDevice->LightEnable(0, TRUE); 21 | 22 | lightHack = true; 23 | } 24 | 25 | void enableLightHackAmbient(LPDIRECT3DDEVICE9 pDevice) 26 | { 27 | pDevice->SetRenderState(D3DRS_AMBIENT, D3DCOLOR_XRGB(100, 100, 100)); 28 | lightHack = true; 29 | } 30 | 31 | void lightHackFrame(DirectXHook* hook, LPDIRECT3DDEVICE9 pDevice) 32 | { 33 | if (!lightHack) 34 | { 35 | if (GetAsyncKeyState(VK_F1)) 36 | enableLightHackDirectional(pDevice); 37 | else if (GetAsyncKeyState(VK_F2)) 38 | enableLightHackAmbient(pDevice); 39 | } 40 | 41 | if (!lightHack) 42 | hook->drawText(10, 188, D3DCOLOR_ARGB(255, 255, 0, 0), "There is currently no lighting. To enable light hack, press F1 for directional or F2 for ambient."); 43 | else 44 | hook->drawText(10, 188, D3DCOLOR_ARGB(255, 255, 0, 0), "Lighthack has been enabled, you should see the cube clearly now."); 45 | } 46 | 47 | 48 | ////////////////// CHAPTER 9 WALLHACK STUFF ////////////////// 49 | bool wallHack = false; 50 | LPDIRECT3DTEXTURE9 redTexture = NULL; 51 | void wallHackFrame(DirectXHook* hook, LPDIRECT3DDEVICE9 pDevice) 52 | { 53 | if (!wallHack && GetAsyncKeyState(VK_F3)) 54 | wallHack = true; 55 | 56 | if (!wallHack) 57 | hook->drawText(10, 203, D3DCOLOR_ARGB(255, 255, 0, 0), "Wallhack example isnt running! Press F3 to enable."); 58 | else 59 | hook->drawText(10, 203, D3DCOLOR_ARGB(255, 255, 0, 0), "Wallhack is enabled! The cube should be drawn in red with no z-buffering now!"); 60 | } 61 | 62 | void onDrawIndexedPrimitive(DirectXHook* hook, LPDIRECT3DDEVICE9 device, D3DPRIMITIVETYPE primType, INT baseVertexIndex, UINT minVertexIndex, UINT numVertices, UINT startIndex, UINT primCount) 63 | { 64 | primitivesDrawn++; 65 | 66 | if (wallHack && numVertices == 24 && primCount == 12) 67 | { 68 | device->SetRenderState(D3DRS_ZENABLE, false); 69 | if (redTexture) device->SetTexture(0, redTexture); 70 | DirectXHook::origDrawIndexedPrimitive(device, primType, baseVertexIndex, minVertexIndex, numVertices, startIndex, primCount); 71 | device->SetRenderState(D3DRS_ZENABLE, true); 72 | } 73 | } 74 | 75 | 76 | ////////////////// CHAPTER 8 STUFF ////////////////// 77 | void initialize(LPDIRECT3DDEVICE9 pDevice) 78 | { 79 | gliderImage = DirectXHook::getInstance()->addSpriteImage(L"glider.png"); 80 | redTexture = DirectXHook::getInstance()->addTexture(L"red.png"); // CHAPTER 9 WALLHACK STUFF 81 | 82 | initialized = true; 83 | } 84 | 85 | void onDrawFrame(DirectXHook* hook, LPDIRECT3DDEVICE9 pDevice) 86 | { 87 | if (!initialized) initialize(pDevice); 88 | 89 | hook->drawText(10, 10, D3DCOLOR_ARGB(255, 255, 0, 0), "Direct3D hook working! Intercepted drawing of %d primitives!", primitivesDrawn); 90 | hook->drawText(10, 25, D3DCOLOR_ARGB(255, 255, 0, 0), "Image drawn by hook:"); 91 | hook->drawSpriteImage(gliderImage, 10, 40, 128, 128); 92 | 93 | lightHackFrame(hook, pDevice); // CHAPTER 9 LIGTHACK STUFF 94 | wallHackFrame(hook, pDevice); // CHAPTER 9 WALLHACK STUFF 95 | 96 | primitivesDrawn = 0; 97 | } 98 | 99 | void onDrawPrimitive(DirectXHook* hook, LPDIRECT3DDEVICE9 pDevice, D3DPRIMITIVETYPE PrimitiveType, UINT StartVertex, UINT PrimitiveCount) 100 | { 101 | primitivesDrawn++; 102 | } 103 | 104 | 105 | DWORD WINAPI LoopFunction(LPVOID lpParam) 106 | { 107 | DirectXHook::getInstance()->addDrawFrameCallback(&onDrawFrame); 108 | DirectXHook::getInstance()->addDrawPrimitiveCallback(&onDrawPrimitive); 109 | DirectXHook::getInstance()->addDrawIndexedPrimitiveCallback(&onDrawIndexedPrimitive); 110 | DirectXHook::getInstance()->initialize(); 111 | 112 | return 0; 113 | } 114 | 115 | BOOL WINAPI DllMain(HMODULE hModule, DWORD dwReason, LPVOID lpvReserved) 116 | { 117 | if(dwReason == DLL_PROCESS_ATTACH) 118 | { 119 | CreateThread(0, 0, LoopFunction, 0, 0, 0); 120 | } 121 | else if(dwReason == DLL_PROCESS_DETACH) 122 | { 123 | 124 | } 125 | 126 | return TRUE; 127 | } -------------------------------------------------------------------------------- /Chapter8_Direct3DHook/memory.h: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameHackingBook/GameHackingCode/601b16c5d1a7d691264fa68312c3af977d2dcefd/Chapter8_Direct3DHook/memory.h -------------------------------------------------------------------------------- /LuaScripts/Chapter1_SearchingForAssemblyPatterns.lua: -------------------------------------------------------------------------------- 1 | BASEADDRESS = getAddress("Game.exe") 2 | function LocatePacketCreation(packetType) 3 | for address = BASEADDRESS, (BASEADDRESS + 0x2ffffff) do 4 | local push = readBytes(address, 1, false) 5 | local type = readInteger(address + 1) 6 | local call = readInteger(address + 5) 7 | if (push == 0x68 and type == packetType and call == 0xE8) then 8 | return address 9 | end 10 | end 11 | return 0 12 | end 13 | 14 | FUNCTIONHEADER = { 0xCC, 0x55, 0x8B, 0xEC, 0x6A } 15 | function LocateFunctionHead(checkAddress) 16 | if (checkAddress == 0) then return 0 end 17 | for address = checkAddress, (checkAddress - 0x1fff), -1 do 18 | local match = true 19 | local checkheader = readBytes(address, #FUNCTIONHEADER, true) 20 | for i, v in ipairs(FUNCTIONHEADER) do 21 | if (v ~= checkheader[i]) then 22 | match = false 23 | break 24 | end 25 | end 26 | if (match) then return address + 1 end 27 | end 28 | return 0 29 | end 30 | 31 | local funcAddress = LocateFunctionHead(LocatePacketCreation(0x64)) 32 | if (funcAddress ~= 0) then 33 | print(string.format("0x%x",funcAddress)) 34 | else 35 | print("Not found!") 36 | end -------------------------------------------------------------------------------- /LuaScripts/Chapter1_SearchingForStrings.lua: -------------------------------------------------------------------------------- 1 | BASEADDRESS = getAddress("Game.exe") 2 | function findString(str) 3 | local len = string.len(str) 4 | local chunkSize = 4096 5 | local chunkStep = chunkSize - len 6 | print("Found '" .. str .. "' at:") 7 | for address = BASEADDRESS, (BASEADDRESS + 0x2ffffff), chunkStep do 8 | local chunk = readBytes(address, chunkSize, true) 9 | if (not chunk) then break end 10 | for c = 0, chunkSize-len do 11 | checkForString(address , chunk, c, str, len) 12 | end 13 | end 14 | end 15 | function checkForString(address, chunk, start, str, len) 16 | for i = 1, len do 17 | if (chunk[start+i] ~= string.byte(str, i)) then 18 | return false 19 | end 20 | end 21 | print(string.format("\t0x%x", address + start)) 22 | end 23 | 24 | findString("hello") 25 | findString("world") -------------------------------------------------------------------------------- /LuaScripts/Chapter5_CountLinkedListNodes.lua: -------------------------------------------------------------------------------- 1 | function countLinkedListNodes(nodeAddress) 2 | local counter = 0 3 | local next = readInteger(nodeAddress) 4 | while (next ~= nodeAddress) do 5 | counter = counter + 1 6 | next = readInteger(next) 7 | end 8 | return counter 9 | end -------------------------------------------------------------------------------- /LuaScripts/Chapter5_VerifyLinkedList.lua: -------------------------------------------------------------------------------- 1 | function _verifyLinkedList(address) 2 | local nextItem = readInteger(address) or 0 3 | local previousItem = readInteger(address + 4) or 0 4 | local nextItemBack = readInteger(nextItem + 4) 5 | local previousItemForward = readInteger(previousItem) 6 | 7 | return (address == nextItemBack 8 | and address == previousItemForward) 9 | end 10 | 11 | function isValueInLinkedList(valueAddress) 12 | for address = valueAddress - 8, valueAddress - 48, -4 do 13 | if (_verifyLinkedList(address)) then 14 | return address 15 | end 16 | end 17 | return 0 18 | end 19 | 20 | local node = isValueInLinkedList(addressOfSomeValue) 21 | if (node > 0) then 22 | print(string.format("Value in LL, top of node at 0x0%x", node)) 23 | end -------------------------------------------------------------------------------- /LuaScripts/Chapter5_VerifyMap.lua: -------------------------------------------------------------------------------- 1 | function _verifyMap(address) 2 | local parentItem = readInteger(address + 4) or 0 3 | 4 | local parentLeftItem = readInteger(parentItem + 0) or 0 5 | local parentRightItem = readInteger(parentItem + 8) or 0 6 | 7 | local validParent = 8 | parentLeftItem == address 9 | or parentRightItem == address 10 | if (not validParent) then return false end 11 | 12 | local tries = 0 13 | local lastChecked = parentItem 14 | local parentsParent = readInteger(parentItem + 4) or 0 15 | while (readInteger(parentsParent + 4) ~= lastChecked and tries < 200) do 16 | tries = tries + 1 17 | lastChecked = parentsParent 18 | parentsParent = readInteger(parentsParent + 4) or 0 19 | end 20 | 21 | return readInteger(parentsParent + 4) == lastChecked 22 | end 23 | 24 | 25 | function isValueInMap(valueAddress) 26 | for address = valueAddress - 12, valueAddress - 52, -4 do 27 | if (_verifyMap(address)) then 28 | return address 29 | end 30 | end 31 | return 0 32 | end 33 | 34 | local node = isValueInMap(addressOfSomeValue) 35 | if (node > 0) then 36 | print(string.format("Value in map, top of node at 0x0%x", node)) 37 | end -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | **Please read this before reporting any issues with the code, as it is quite likely to solve your issues!** 2 | 3 | # About 4 | 5 | Code for the book [Game Hacking: Developing Autonomous Bots for Online Games](http://www.nostarch.com/gamehacking). 6 | 7 | Each project in this repository corresponds to a chapter or section in the book. The projects are referenced in the relevant pages. 8 | 9 | # Purpose 10 | The exact purpose of each binary will be explained in the book. Some binaries are meant to be scanned and debugged, others simply exist as proof-of-concepts for lessons, and a few actually illustrate how certain algorithms look with different inputs. 11 | 12 | # Compiling 13 | All of the example code should compile out-of-the-box on Visual Studio 2010, and any newer version. The exception is the two practice binaries for Chapter 1, which rely on the `Allegro 5.0.10` library to be installed with the `bin`, `lib`, and `include` directories properly set up in your Visual Studio paths for additional include directories and additional linker directories. 14 | 15 | If you can't compile yourself, all of the binaries are in the `/bin/` directory. Debug binaries are in the `/bin/DEBUG_BUILDS/` directory with included debug databases. Specifically, there is zero need to compile the binaries for the labs, and these are the ones likely to give you trouble (because of missing Allegro libs). The remaining code should compile fine, as you can poke it and recompile as much as you'd like. 16 | 17 | # Usage 18 | You may need to grab [this redistributable package from Microsoft](https://www.microsoft.com/en-us/download/details.aspx?id=5555) to run the binaries if you don't have Visual Studio. If you get errors about loading fonts or map, move [arial.ttf](https://github.com/GameHackingBook/GameHackingExamples/blob/master/arial.ttf) and [game.map](https://github.com/GameHackingBook/GameHackingExamples/blob/master/game.map) into the same directory as the binary and try again. 19 | 20 | If you for same reason want to use the debug binaries, you will need the debug redistributable installed. This comes with Visual Studio 2010, and you can also find the stand-alone DLLs online. If this gives you trouble, I'd recommend either sticking to the release binaries, or compiling on your local version of Visual studio given the compile steps above. 21 | -------------------------------------------------------------------------------- /allegro_linkers.h: -------------------------------------------------------------------------------- 1 | #pragma comment(lib, "allegro-5.0.10-static-md.lib") 2 | 3 | #pragma comment(lib, "opengl32.lib") 4 | #pragma comment(lib, "glu32.lib") 5 | 6 | #pragma comment(lib, "winmm.LIB") 7 | #pragma comment(lib, "shlwapi.lib") 8 | #pragma comment(lib, "psapi.lib") 9 | 10 | #ifdef _ALLEGRO_FONT_DLL 11 | #include 12 | #pragma comment(lib, "freetype-2.4.8-static-md.lib") 13 | #pragma comment(lib, "allegro_font-5.0.10-static-md.lib") 14 | #pragma comment(lib, "allegro_ttf-5.0.10-static-md.lib") 15 | #endif 16 | 17 | #ifdef _ALLEGRO_DIALOG_DLL 18 | #pragma comment(lib, "allegro_dialog-5.0.10-static-md.lib") 19 | #endif 20 | 21 | #ifdef _ALLEGRO_PRIM_DLL 22 | #pragma comment(lib, "allegro_primitives-5.0.10-static-md.lib") 23 | #endif -------------------------------------------------------------------------------- /arial.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameHackingBook/GameHackingCode/601b16c5d1a7d691264fa68312c3af977d2dcefd/arial.ttf -------------------------------------------------------------------------------- /bin/Chapter10_ResponsiveHacks.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameHackingBook/GameHackingCode/601b16c5d1a7d691264fa68312c3af977d2dcefd/bin/Chapter10_ResponsiveHacks.exe -------------------------------------------------------------------------------- /bin/Chapter11_SearchAlgorithms.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameHackingBook/GameHackingCode/601b16c5d1a7d691264fa68312c3af977d2dcefd/bin/Chapter11_SearchAlgorithms.exe -------------------------------------------------------------------------------- /bin/Chapter11_StateMachines.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameHackingBook/GameHackingCode/601b16c5d1a7d691264fa68312c3af977d2dcefd/bin/Chapter11_StateMachines.exe -------------------------------------------------------------------------------- /bin/Chapter1_BasicMemory.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameHackingBook/GameHackingCode/601b16c5d1a7d691264fa68312c3af977d2dcefd/bin/Chapter1_BasicMemory.exe -------------------------------------------------------------------------------- /bin/Chapter1_MemoryPointers.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameHackingBook/GameHackingCode/601b16c5d1a7d691264fa68312c3af977d2dcefd/bin/Chapter1_MemoryPointers.exe -------------------------------------------------------------------------------- /bin/Chapter2_BasicDebugging.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameHackingBook/GameHackingCode/601b16c5d1a7d691264fa68312c3af977d2dcefd/bin/Chapter2_BasicDebugging.exe -------------------------------------------------------------------------------- /bin/Chapter3_CloseMutex.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameHackingBook/GameHackingCode/601b16c5d1a7d691264fa68312c3af977d2dcefd/bin/Chapter3_CloseMutex.exe -------------------------------------------------------------------------------- /bin/Chapter3_FindingFiles.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameHackingBook/GameHackingCode/601b16c5d1a7d691264fa68312c3af977d2dcefd/bin/Chapter3_FindingFiles.exe -------------------------------------------------------------------------------- /bin/Chapter4_CodeToMemory.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameHackingBook/GameHackingCode/601b16c5d1a7d691264fa68312c3af977d2dcefd/bin/Chapter4_CodeToMemory.exe -------------------------------------------------------------------------------- /bin/Chapter5_AdvancedMemoryForensics_Scanning.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameHackingBook/GameHackingCode/601b16c5d1a7d691264fa68312c3af977d2dcefd/bin/Chapter5_AdvancedMemoryForensics_Scanning.exe -------------------------------------------------------------------------------- /bin/Chapter6_AccessingMemory.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameHackingBook/GameHackingCode/601b16c5d1a7d691264fa68312c3af977d2dcefd/bin/Chapter6_AccessingMemory.exe -------------------------------------------------------------------------------- /bin/Chapter7_CodeInjection.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameHackingBook/GameHackingCode/601b16c5d1a7d691264fa68312c3af977d2dcefd/bin/Chapter7_CodeInjection.exe -------------------------------------------------------------------------------- /bin/Chapter8_ControlFlow.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameHackingBook/GameHackingCode/601b16c5d1a7d691264fa68312c3af977d2dcefd/bin/Chapter8_ControlFlow.exe -------------------------------------------------------------------------------- /bin/Chapter8_Direct3DApplication.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameHackingBook/GameHackingCode/601b16c5d1a7d691264fa68312c3af977d2dcefd/bin/Chapter8_Direct3DApplication.exe -------------------------------------------------------------------------------- /bin/DEBUG_BUILDS/Chapter10_ResponsiveHacks.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameHackingBook/GameHackingCode/601b16c5d1a7d691264fa68312c3af977d2dcefd/bin/DEBUG_BUILDS/Chapter10_ResponsiveHacks.exe -------------------------------------------------------------------------------- /bin/DEBUG_BUILDS/Chapter10_ResponsiveHacks.ilk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameHackingBook/GameHackingCode/601b16c5d1a7d691264fa68312c3af977d2dcefd/bin/DEBUG_BUILDS/Chapter10_ResponsiveHacks.ilk -------------------------------------------------------------------------------- /bin/DEBUG_BUILDS/Chapter10_ResponsiveHacks.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameHackingBook/GameHackingCode/601b16c5d1a7d691264fa68312c3af977d2dcefd/bin/DEBUG_BUILDS/Chapter10_ResponsiveHacks.pdb -------------------------------------------------------------------------------- /bin/DEBUG_BUILDS/Chapter11_SearchAlgorithms.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameHackingBook/GameHackingCode/601b16c5d1a7d691264fa68312c3af977d2dcefd/bin/DEBUG_BUILDS/Chapter11_SearchAlgorithms.exe -------------------------------------------------------------------------------- /bin/DEBUG_BUILDS/Chapter11_SearchAlgorithms.ilk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameHackingBook/GameHackingCode/601b16c5d1a7d691264fa68312c3af977d2dcefd/bin/DEBUG_BUILDS/Chapter11_SearchAlgorithms.ilk -------------------------------------------------------------------------------- /bin/DEBUG_BUILDS/Chapter11_SearchAlgorithms.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameHackingBook/GameHackingCode/601b16c5d1a7d691264fa68312c3af977d2dcefd/bin/DEBUG_BUILDS/Chapter11_SearchAlgorithms.pdb -------------------------------------------------------------------------------- /bin/DEBUG_BUILDS/Chapter11_StateMachines.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameHackingBook/GameHackingCode/601b16c5d1a7d691264fa68312c3af977d2dcefd/bin/DEBUG_BUILDS/Chapter11_StateMachines.exe -------------------------------------------------------------------------------- /bin/DEBUG_BUILDS/Chapter11_StateMachines.ilk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameHackingBook/GameHackingCode/601b16c5d1a7d691264fa68312c3af977d2dcefd/bin/DEBUG_BUILDS/Chapter11_StateMachines.ilk -------------------------------------------------------------------------------- /bin/DEBUG_BUILDS/Chapter11_StateMachines.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameHackingBook/GameHackingCode/601b16c5d1a7d691264fa68312c3af977d2dcefd/bin/DEBUG_BUILDS/Chapter11_StateMachines.pdb -------------------------------------------------------------------------------- /bin/DEBUG_BUILDS/Chapter1_BasicMemory.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameHackingBook/GameHackingCode/601b16c5d1a7d691264fa68312c3af977d2dcefd/bin/DEBUG_BUILDS/Chapter1_BasicMemory.exe -------------------------------------------------------------------------------- /bin/DEBUG_BUILDS/Chapter1_BasicMemory.ilk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameHackingBook/GameHackingCode/601b16c5d1a7d691264fa68312c3af977d2dcefd/bin/DEBUG_BUILDS/Chapter1_BasicMemory.ilk -------------------------------------------------------------------------------- /bin/DEBUG_BUILDS/Chapter1_BasicMemory.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameHackingBook/GameHackingCode/601b16c5d1a7d691264fa68312c3af977d2dcefd/bin/DEBUG_BUILDS/Chapter1_BasicMemory.pdb -------------------------------------------------------------------------------- /bin/DEBUG_BUILDS/Chapter1_MemoryPointers.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameHackingBook/GameHackingCode/601b16c5d1a7d691264fa68312c3af977d2dcefd/bin/DEBUG_BUILDS/Chapter1_MemoryPointers.exe -------------------------------------------------------------------------------- /bin/DEBUG_BUILDS/Chapter1_MemoryPointers.ilk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameHackingBook/GameHackingCode/601b16c5d1a7d691264fa68312c3af977d2dcefd/bin/DEBUG_BUILDS/Chapter1_MemoryPointers.ilk -------------------------------------------------------------------------------- /bin/DEBUG_BUILDS/Chapter1_MemoryPointers.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameHackingBook/GameHackingCode/601b16c5d1a7d691264fa68312c3af977d2dcefd/bin/DEBUG_BUILDS/Chapter1_MemoryPointers.pdb -------------------------------------------------------------------------------- /bin/DEBUG_BUILDS/Chapter2_BasicDebugging.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameHackingBook/GameHackingCode/601b16c5d1a7d691264fa68312c3af977d2dcefd/bin/DEBUG_BUILDS/Chapter2_BasicDebugging.exe -------------------------------------------------------------------------------- /bin/DEBUG_BUILDS/Chapter2_BasicDebugging.ilk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameHackingBook/GameHackingCode/601b16c5d1a7d691264fa68312c3af977d2dcefd/bin/DEBUG_BUILDS/Chapter2_BasicDebugging.ilk -------------------------------------------------------------------------------- /bin/DEBUG_BUILDS/Chapter2_BasicDebugging.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameHackingBook/GameHackingCode/601b16c5d1a7d691264fa68312c3af977d2dcefd/bin/DEBUG_BUILDS/Chapter2_BasicDebugging.pdb -------------------------------------------------------------------------------- /bin/DEBUG_BUILDS/Chapter3_CloseMutex.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameHackingBook/GameHackingCode/601b16c5d1a7d691264fa68312c3af977d2dcefd/bin/DEBUG_BUILDS/Chapter3_CloseMutex.exe -------------------------------------------------------------------------------- /bin/DEBUG_BUILDS/Chapter3_CloseMutex.ilk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameHackingBook/GameHackingCode/601b16c5d1a7d691264fa68312c3af977d2dcefd/bin/DEBUG_BUILDS/Chapter3_CloseMutex.ilk -------------------------------------------------------------------------------- /bin/DEBUG_BUILDS/Chapter3_CloseMutex.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameHackingBook/GameHackingCode/601b16c5d1a7d691264fa68312c3af977d2dcefd/bin/DEBUG_BUILDS/Chapter3_CloseMutex.pdb -------------------------------------------------------------------------------- /bin/DEBUG_BUILDS/Chapter3_FindingFiles.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameHackingBook/GameHackingCode/601b16c5d1a7d691264fa68312c3af977d2dcefd/bin/DEBUG_BUILDS/Chapter3_FindingFiles.exe -------------------------------------------------------------------------------- /bin/DEBUG_BUILDS/Chapter3_FindingFiles.ilk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameHackingBook/GameHackingCode/601b16c5d1a7d691264fa68312c3af977d2dcefd/bin/DEBUG_BUILDS/Chapter3_FindingFiles.ilk -------------------------------------------------------------------------------- /bin/DEBUG_BUILDS/Chapter3_FindingFiles.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameHackingBook/GameHackingCode/601b16c5d1a7d691264fa68312c3af977d2dcefd/bin/DEBUG_BUILDS/Chapter3_FindingFiles.pdb -------------------------------------------------------------------------------- /bin/DEBUG_BUILDS/Chapter4_CodeToMemory.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameHackingBook/GameHackingCode/601b16c5d1a7d691264fa68312c3af977d2dcefd/bin/DEBUG_BUILDS/Chapter4_CodeToMemory.exe -------------------------------------------------------------------------------- /bin/DEBUG_BUILDS/Chapter4_CodeToMemory.ilk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameHackingBook/GameHackingCode/601b16c5d1a7d691264fa68312c3af977d2dcefd/bin/DEBUG_BUILDS/Chapter4_CodeToMemory.ilk -------------------------------------------------------------------------------- /bin/DEBUG_BUILDS/Chapter4_CodeToMemory.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameHackingBook/GameHackingCode/601b16c5d1a7d691264fa68312c3af977d2dcefd/bin/DEBUG_BUILDS/Chapter4_CodeToMemory.pdb -------------------------------------------------------------------------------- /bin/DEBUG_BUILDS/Chapter5_AdvancedMemoryForensics_Scanning.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameHackingBook/GameHackingCode/601b16c5d1a7d691264fa68312c3af977d2dcefd/bin/DEBUG_BUILDS/Chapter5_AdvancedMemoryForensics_Scanning.exe -------------------------------------------------------------------------------- /bin/DEBUG_BUILDS/Chapter5_AdvancedMemoryForensics_Scanning.ilk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameHackingBook/GameHackingCode/601b16c5d1a7d691264fa68312c3af977d2dcefd/bin/DEBUG_BUILDS/Chapter5_AdvancedMemoryForensics_Scanning.ilk -------------------------------------------------------------------------------- /bin/DEBUG_BUILDS/Chapter5_AdvancedMemoryForensics_Scanning.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameHackingBook/GameHackingCode/601b16c5d1a7d691264fa68312c3af977d2dcefd/bin/DEBUG_BUILDS/Chapter5_AdvancedMemoryForensics_Scanning.pdb -------------------------------------------------------------------------------- /bin/DEBUG_BUILDS/Chapter6_AccessingMemory.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameHackingBook/GameHackingCode/601b16c5d1a7d691264fa68312c3af977d2dcefd/bin/DEBUG_BUILDS/Chapter6_AccessingMemory.exe -------------------------------------------------------------------------------- /bin/DEBUG_BUILDS/Chapter6_AccessingMemory.ilk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameHackingBook/GameHackingCode/601b16c5d1a7d691264fa68312c3af977d2dcefd/bin/DEBUG_BUILDS/Chapter6_AccessingMemory.ilk -------------------------------------------------------------------------------- /bin/DEBUG_BUILDS/Chapter6_AccessingMemory.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameHackingBook/GameHackingCode/601b16c5d1a7d691264fa68312c3af977d2dcefd/bin/DEBUG_BUILDS/Chapter6_AccessingMemory.pdb -------------------------------------------------------------------------------- /bin/DEBUG_BUILDS/Chapter7_CodeInjection.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameHackingBook/GameHackingCode/601b16c5d1a7d691264fa68312c3af977d2dcefd/bin/DEBUG_BUILDS/Chapter7_CodeInjection.exe -------------------------------------------------------------------------------- /bin/DEBUG_BUILDS/Chapter7_CodeInjection.ilk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameHackingBook/GameHackingCode/601b16c5d1a7d691264fa68312c3af977d2dcefd/bin/DEBUG_BUILDS/Chapter7_CodeInjection.ilk -------------------------------------------------------------------------------- /bin/DEBUG_BUILDS/Chapter7_CodeInjection.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameHackingBook/GameHackingCode/601b16c5d1a7d691264fa68312c3af977d2dcefd/bin/DEBUG_BUILDS/Chapter7_CodeInjection.pdb -------------------------------------------------------------------------------- /bin/DEBUG_BUILDS/Chapter7_CodeInjection_DLL.ilk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameHackingBook/GameHackingCode/601b16c5d1a7d691264fa68312c3af977d2dcefd/bin/DEBUG_BUILDS/Chapter7_CodeInjection_DLL.ilk -------------------------------------------------------------------------------- /bin/DEBUG_BUILDS/Chapter7_CodeInjection_DLL.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameHackingBook/GameHackingCode/601b16c5d1a7d691264fa68312c3af977d2dcefd/bin/DEBUG_BUILDS/Chapter7_CodeInjection_DLL.pdb -------------------------------------------------------------------------------- /bin/DEBUG_BUILDS/Chapter8_AdobeAirHook.ilk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameHackingBook/GameHackingCode/601b16c5d1a7d691264fa68312c3af977d2dcefd/bin/DEBUG_BUILDS/Chapter8_AdobeAirHook.ilk -------------------------------------------------------------------------------- /bin/DEBUG_BUILDS/Chapter8_AdobeAirHook.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameHackingBook/GameHackingCode/601b16c5d1a7d691264fa68312c3af977d2dcefd/bin/DEBUG_BUILDS/Chapter8_AdobeAirHook.pdb -------------------------------------------------------------------------------- /bin/DEBUG_BUILDS/Chapter8_ControlFlow.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameHackingBook/GameHackingCode/601b16c5d1a7d691264fa68312c3af977d2dcefd/bin/DEBUG_BUILDS/Chapter8_ControlFlow.exe -------------------------------------------------------------------------------- /bin/DEBUG_BUILDS/Chapter8_ControlFlow.ilk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameHackingBook/GameHackingCode/601b16c5d1a7d691264fa68312c3af977d2dcefd/bin/DEBUG_BUILDS/Chapter8_ControlFlow.ilk -------------------------------------------------------------------------------- /bin/DEBUG_BUILDS/Chapter8_ControlFlow.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameHackingBook/GameHackingCode/601b16c5d1a7d691264fa68312c3af977d2dcefd/bin/DEBUG_BUILDS/Chapter8_ControlFlow.pdb -------------------------------------------------------------------------------- /bin/DEBUG_BUILDS/Chapter8_Direct3DApplication.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameHackingBook/GameHackingCode/601b16c5d1a7d691264fa68312c3af977d2dcefd/bin/DEBUG_BUILDS/Chapter8_Direct3DApplication.exe -------------------------------------------------------------------------------- /bin/DEBUG_BUILDS/Chapter8_Direct3DApplication.ilk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameHackingBook/GameHackingCode/601b16c5d1a7d691264fa68312c3af977d2dcefd/bin/DEBUG_BUILDS/Chapter8_Direct3DApplication.ilk -------------------------------------------------------------------------------- /bin/DEBUG_BUILDS/Chapter8_Direct3DApplication.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameHackingBook/GameHackingCode/601b16c5d1a7d691264fa68312c3af977d2dcefd/bin/DEBUG_BUILDS/Chapter8_Direct3DApplication.pdb -------------------------------------------------------------------------------- /bin/DEBUG_BUILDS/Chapter8_Direct3DHook.ilk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameHackingBook/GameHackingCode/601b16c5d1a7d691264fa68312c3af977d2dcefd/bin/DEBUG_BUILDS/Chapter8_Direct3DHook.ilk -------------------------------------------------------------------------------- /bin/DEBUG_BUILDS/Chapter8_Direct3DHook.pdb: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GameHackingBook/GameHackingCode/601b16c5d1a7d691264fa68312c3af977d2dcefd/bin/DEBUG_BUILDS/Chapter8_Direct3DHook.pdb -------------------------------------------------------------------------------- /game.map: -------------------------------------------------------------------------------- 1 |  --------------------------------------------------------------------------------