This shows you the differences between two versions of the page.
so:laboratoare:resurse:injections [2013/02/19 09:05] larisa.grigore [Dll Injection] |
so:laboratoare:resurse:injections [2016/03/09 12:34] (current) dennis.plosceanu [Function Hooking and Windows Dll Injection] Ordinea cuvintelor in engleza |
||
---|---|---|---|
Line 1: | Line 1: | ||
====== Function Hooking and Windows Dll Injection ====== | ====== Function Hooking and Windows Dll Injection ====== | ||
- | In this tutorial I'll show you how to modify at runtime the behavior of Windows programs. | + | In this tutorial I'll show you how to modify the behavior of Windows programs at runtime. |
===== Function Hot Patching ===== | ===== Function Hot Patching ===== | ||
Line 12: | Line 12: | ||
Here's a better solution: modify ''foo()'' at runtime by writing your code inside it! | Here's a better solution: modify ''foo()'' at runtime by writing your code inside it! | ||
- | <spoiler|asm break> | + | <spoiler> |
Strictly speaking, you call a function by ''push''-ing some stuff like the arguments into the stack and then by executing ''call //function address//''. Since we're discussing C, when the function returns, you ''pop'' those arguments from the stack to keep it from thrashing. For example (this is debug code, notice the sanity check at ''00F9145E''): | Strictly speaking, you call a function by ''push''-ing some stuff like the arguments into the stack and then by executing ''call //function address//''. Since we're discussing C, when the function returns, you ''pop'' those arguments from the stack to keep it from thrashing. For example (this is debug code, notice the sanity check at ''00F9145E''): | ||
Line 190: | Line 190: | ||
As a first attempt I created a simple one-shot console application that targeted the Heroes of Newerth window, removing the ''WS_CAPTION'' style, as reported by Spy++. | As a first attempt I created a simple one-shot console application that targeted the Heroes of Newerth window, removing the ''WS_CAPTION'' style, as reported by Spy++. | ||
- | {{ :laboratoare:resurse:home:hon01.png?640 |Heroes of Newerth window styles}} | + | {{ so:laboratoare:resurse:home:hon01.png?640 |Heroes of Newerth window styles}} |
<file cpp Borderless1.cpp> | <file cpp Borderless1.cpp> | ||
Line 219: | Line 219: | ||
</file> | </file> | ||
- | {{ :laboratoare:resurse:home:hon02.png?640 |Heroes of Newerth borderless}} | + | {{ so:laboratoare:resurse:home:hon02.png?640 |Heroes of Newerth borderless}} |
You can observe 2 problems in the current approach: | You can observe 2 problems in the current approach: | ||
Line 292: | Line 292: | ||
For the broken mouse hover effect it's time to put The Injection to use! Among the usual suspects for this problem are the window rectangle functions [[http://msdn.microsoft.com/en-us/library/ms633519%28VS.85%29.aspx|GetWindowRect()]] and [[http://msdn.microsoft.com/en-us/library/ms633503%28VS.85%29.aspx|GetClientRect()]]. It would make sense, due to the fact that games usually obtain mouse events through DirectInput, that initially mouse coordinates are expressed in desktop-absolute form, and not relative to the application window. Therefore they'd have to employ, in one form or another a conversion between screen (absolute) coordinates and window coordinates in a similar manner to the operation of [[http://msdn.microsoft.com/en-us/library/aa931003.aspx|ClientToScreen()]]. | For the broken mouse hover effect it's time to put The Injection to use! Among the usual suspects for this problem are the window rectangle functions [[http://msdn.microsoft.com/en-us/library/ms633519%28VS.85%29.aspx|GetWindowRect()]] and [[http://msdn.microsoft.com/en-us/library/ms633503%28VS.85%29.aspx|GetClientRect()]]. It would make sense, due to the fact that games usually obtain mouse events through DirectInput, that initially mouse coordinates are expressed in desktop-absolute form, and not relative to the application window. Therefore they'd have to employ, in one form or another a conversion between screen (absolute) coordinates and window coordinates in a similar manner to the operation of [[http://msdn.microsoft.com/en-us/library/aa931003.aspx|ClientToScreen()]]. | ||
Let's take a look at an application window and the ''Get?Rect()'' logic relating to it: | Let's take a look at an application window and the ''Get?Rect()'' logic relating to it: | ||
- | {{ :laboratoare:resurse:home:sc201.png?w640 |Window rectangles}} | + | {{ so:laboratoare:resurse:home:sc201.png?w640 |Window rectangles}} |
What the game does when handling mouse input is obtain some absolute screen coordinates from DirectInput, convert them to window coordinates, then **compensate** for the window title and borders and then figure out what to do next with the event. Note that after removing the window decorations, both ''GetWindowRect()'' and ''GetClientRect()'' return the same coordinates. Then the game compensates by subtracting the expected widths and heights of borders, resulting in slightly off readings for the events. The idea here is to modify at run-time ''GetWindowRect()'' so that it returns the old rectangle, with titlebar and borders, as if the window style still contained those elements. | What the game does when handling mouse input is obtain some absolute screen coordinates from DirectInput, convert them to window coordinates, then **compensate** for the window title and borders and then figure out what to do next with the event. Note that after removing the window decorations, both ''GetWindowRect()'' and ''GetClientRect()'' return the same coordinates. Then the game compensates by subtracting the expected widths and heights of borders, resulting in slightly off readings for the events. The idea here is to modify at run-time ''GetWindowRect()'' so that it returns the old rectangle, with titlebar and borders, as if the window style still contained those elements. | ||
Line 356: | Line 356: | ||
</code> | </code> | ||
- | {{ :laboratoare:resurse:home:guest3264.png?w=512 |32 bit guest and 64 bit stub}} | + | {{ so:laboratoare:resurse:home:guest3264.png?w=512 |32 bit guest and 64 bit stub}} |
====== Download ====== | ====== Download ====== | ||
- | All the required code can be found {{:laboratoare:resurse:injections.7z|here}}. Note that the project files won't work with the Express version of Visual Studio, due to the main program - ''Deframe'' being written with ''MFC''. | + | All the required code can be found {{so:laboratoare:resurse:injections.7z|here}}. Note that the project files won't work with the Express version of Visual Studio, due to the main program - ''Deframe'' being written with ''MFC''. |
- | For a binary build, see {{:laboratoare:resurse:deframe-5-no-mfc.7z|this archive}}. | + | For a binary build, see {{so:laboratoare:resurse:deframe-5-no-mfc.7z|this archive}}. |
The solution uses a C-like approach for the Injection. The workflow is: | The solution uses a C-like approach for the Injection. The workflow is: | ||
- start Deframe.exe | - start Deframe.exe | ||
Line 368: | Line 368: | ||
- select either of the 2 available options ''On top'' or ''No borders'' | - select either of the 2 available options ''On top'' or ''No borders'' | ||
- | {{ :laboratoare:resurse:home:system_menu.png?w640 |The system menu in Diablo III}} | + | {{ so:laboratoare:resurse:home:system_menu.png?w640 |The system menu in Diablo III}} |
===== A C++ Template Library (for the impatient) ===== | ===== A C++ Template Library (for the impatient) ===== | ||