This is the first article in a series I am going to write explaining my COF plugin for day of defeat source. For those unfamiliar with it, heres a basic run down. In day of defeat source, there is no shot distribution as in most games. For instance, half life 2 and counter strike source feature an expanding cone of fire. When your fire a shot the longer you spray the less accurate you become, basically. In day of defeat source however, the area your bullets can land is constant and completely random. Picture flighting with a flashlight, where you and your enemies point your lights at each other and wait for a bullet to hit someone.
Obviously this feature broke day of defeat source, and many professional day of defeat players did not pick up the game, thats where this hack comes in. My plugin successfully detoured the server’s shot distribution code into my own function that gave the bullets some center-weight. So that bullets tended to land where your cross hair was, instead of anywhere in an area around your cross hair.
The idea is hard to convey in written words, but the plugin is of no meaning to this article, just an example.
So first off lets start out with the hardest part of any detour or memory hack, finding the target.
You need a disassembler, hopefully you have one and are used to using it if you have stumbled across this article. Some good ones I can recommend is PE Explorer, win32dasm, and if you can find it, IDA. I use IDA now after using PE Explorer for quite a while, and I highly recommend it.
If you want to follow along with my example you can download an older version of the day of defeat source server windows binary here and the linux binary here.
Now what you need to do is find the section of code you wish to change. In this case, we want to change the shot distribution. Half life source mods comes with two program dll’s, a client.dll and server.dll. As expected the client library controls all actions and events on the client and the server library controls the server. In the case of this hack I had suitable source to use as a reference, namely, the source sdk. So after a bit of research I found that a section of code in shot_manipulator.h handled the shot distribution. Inside I found this:
//———————————————————
// Take a vector (direction) and another vector (spread)
// and modify the direction to point somewhere within the
// spread. This used to live inside FireBullets.
//———————————————————
inline const Vector &CShotManipulator::ApplySpread( const Vector &vecSpread, float bias )
{
// get circular gaussian spread
float x, y, z;if ( bias > 1.0 )
bias = 1.0;
else if ( bias < 0.0 )
bias = 0.0;float shotBiasMin = ai_shot_bias_min.GetFloat();
float shotBiasMax = ai_shot_bias_max.GetFloat();// 1.0 gaussian, 0.0 is flat, -1.0 is inverse gaussian
float shotBias = ( ( shotBiasMax – shotBiasMin ) * bias ) + shotBiasMin;float flatness = ( fabsf(shotBias) * 0.5 );
do
{
x = random->RandomFloat(-1,1) * flatness + random->RandomFloat(-1,1) * (1 – flatness);
y = random->RandomFloat(-1,1) * flatness + random->RandomFloat(-1,1) * (1 – flatness);
if ( shotBias < 0 )
{
x = ( x >= 0 ) ? 1.0 – x : -1.0 – x;
y = ( y >= 0 ) ? 1.0 – y : -1.0 – y;
}
z = x*x+y*y;
} while (z > 1);m_vecResult = m_vecShotDirection + x * vecSpread.x * m_vecRight + y * vecSpread.y * m_vecUp;
return m_vecResult;
}
There are a couple options at this point, you can see that there are multiple calls to RandomFloat with the argument -1 and 1, going a bit further we find that these are floating point numbers, and this translate into 3F800000 you can do this translation on a napkin or use FPConvert.
What you can do is search the binary for repetitive push’s of 3F800000 or you can trace the function back and find out the actual (non-inline) functions that call it. In this case there are a few in the standard source tree, however after some experimentation you can find that the FireBullets function is the real deal.
I have you look for “push 3F800000″ because in assembly, when the compiler wants to call a function it first pushes the arguments onto the stack. So what you are really looking for is something like this:
push 3F800000
push BF800000
call ABCDEF00
I said there were a couple options because of this fact, not all programs you try and detour will have linux binaries. In this case, it is simply a matter of disassembling the linux so file and searching for FireBullets, you end up finding a symbol called “FX_FireBullets” which calculates shot distribution. For those who do not know, linux so files usually contain symbol names for each function it has. And these symbol names very nicely correspond to the actual function name.
However if you were going the hard way and had only a windows binary you would have to check every “push 3F800000″ to see if it looks like it would be apart of the source code above. You will probably find multiple locations which takes us to step two.
Part One Conclusion:
Obviously if you are reading this you probably have a vastly different project on your hands that you wish to implement a detour on. The goal of this first post was to try and explain the method for finding the right location in a binary file, no small task considering the size of todays programs. And we are still not done, if you are following this example you will have noticed that there are three or four likely locations for shot calculating, in the next section I will explain how to slowly nail down the correct address using a hex editor.
Tags: disassemble, Games, hacking, series, tutorial

No comments
Comments feed for this article
Trackback link: http://charlessolar.com/post/4/trackback