Chapter 8. Removing the Cheating Elements

Lest you believe that you need not worry about cheating, you should perhaps think again. As PCs get more sophisticated, they can be used not only to play games, but also to cheat on them. Indeed, cheating can occur in as many ways as there are network games. It is the game designer’s responsibility to make sure that the game cannot be cheated, and to police any infractions that do occur either manually or automatically. How seriously the designer takes this role will have an impact on the long-term popularity of the game.

While it would be impossible to cover them all, this chapter at least looks at why cheating occurs, what form it takes, and ways to combat it. Specifically, this chapter looks at two kinds of cheats:

  • Augmentation. This involves helping the player to be better than (in some cases) humanly possible.

  • Logic-layer cheats. These involve fooling the client and server into believing that the player is better than he or she is or that the game has progressed on the client side in a fashion not logically possible.

It also looks at key ways in which cheat detection can be implemented—not only to catch people using bots to play games in an automated fashion, but to catch other types of cheats as well, such as data insertion and other attempts to fool the server or other clients that the game is unfolding in a way that is both beneficial to a specific client and not an accurate reflection of reality. It then covers possible actions that can be taken against cheating within the game itself, with the worst offenders receiving a total ban and plenty of other sanctions in between.

Note

Logic-layer cheats.

The kinds of cheats that are the most difficult to catch are ones who act within the rules of the game, including automated players. These are hard to detect and prevent, as they don’t tend to draw attention to themselves.

Apart from this is the possibility that cheating elements can simply be factored out (ignored)—that is, either cheating doesn’t happen in the first place or its effects are minimal. To achieve this, the problem must be approached on several levels:

  • The network and the data that it carries

  • The client, the decisions that it is allowed to make, and the data that it generates

  • The server and how it processes the game environment

Before we get into that, however, we must first define what game designers perceive as cheating, and where the risks lie.

What Is Cheating?

Sometimes, a fine line exists between behavior that might be considered cheating and that which might just be considered competitive. Behavior that falls in this gray area might be ignored, as it doesn’t detract immediately from everyone’s enjoyment.

Despite the insistence of Greg Costikyan, in his 2000 article “The Future of Online Gaming” [COS01] that

“An online game’s success or failure is largely determined by how the players are treated. In other words, the customer experience—in this case the player experience—is the key driver of online success,”

many game designers, players, and those running the game turn a blind eye to a detrimental player experience caused by cheating as long as said cheating does not affect the bottom line. And that’s at the root of the problem—or, as Matt Pritchard [GAMA01] puts it:

“Cheating undermines success.”

Pinpointing a single definition for cheating is a bit more difficult than you might think. Cheating takes many different forms, and its effects are felt in so many different ways, that it is hard to point to one single behavior as cheating personified. That said, a reasonable definition might be “a playing style that exploits the system to the personal benefit of the individual.” The focus here is the fact that cheating should give the player an unfair advantage; otherwise, what would be the point? Another type of cheating might be behavior that is aimed at damaging the playing experience of the other players—but again, the player doing the cheating likely does so to gain an unfair competitive advantage (although in some cases, it might just be the thrill of disrupting others’ gaming experience).

Then again, some things that you might think of as cheating may not be. For example, although the practice is usually frowned upon by game manufacturers—and may violate the terms of use—selling in-game currency, or entire accounts containing leveled-up characters, on the Internet is not considered to be cheating, as it does not detrimentally affect the game and those playing it. That’s not to say that doing so is strictly on the up and up; after all, it enables people to artificially advance or benefit from additional weapons, removing the hard graft that comes with the natural progression of the player through the game’s leveling system.

Note

What Is Cheating?

Certain questions arise that transcend the issues surrounding cheating and automated playing, namely Is a player who spends time building up a character for the sole purpose of selling it on cheating? By same token, is the person who buys it also cheating? Either way, it is a waste of resources to try to deal with this kind of cheating when there are automated processes that can reduce overall cheating of the kind that is actually detrimental to the experience of all the players rather than just one or two.

There is a thin line between what might constitute cheating and what definitely is. It’s hard to point to one particular thing and say that it is always cheating—except in cases where the natural capabilities of the player are enhanced or where the game is played outside its own rules.

Before you can look in any detail at the causes of, effects of, and ways to combat cheating, you must first consider where the risks lie. Clearly, single-player games are not at risk in the same way, because cheaters benefit only themselves by cheating—and if they want to do that, that is up to them. But where do the risks lie for multi-player network games?

What Are the Risks?

Different games have different risks associated with them. In other words, different games have different mechanisms by which it is possible to cheat—and in some cases, a game’s implementation makes it more susceptible to cheating than others. For example, a game that uses text-based commands is at high risk for cheating of all kinds, the reason being that any game in which data that is transferred is encoded as pure text will be very easy to spoof. After all, in the case of a MUD with a Telnet-based front-end, for example, the server has no way of determining whether the client is a machine or a human. Furthermore, the plain-text nature of the commands means that the machine can very easily introduce them into the data stream. What’s more, the cheater doesn’t have to go to any lengths to try to figure out the game’s command API, seeing as how it’s the very same sequences of characters used to play the game. That is, there’s no translation from keyboard to game, as there is in a sophisticated shooting game with a specialized client front-end.

By the way, speaking of sophisticated shooting games with specialized client front-ends: These are not safe, either. Indeed, client software games are very high risk, regardless of whether the client is a full game engine with a multi-player component or simply an advanced client front-end. The risk is high for one simple reason: The tools needed to construct elaborate hacks are placed right in the hands of the hackers. Hackers have access to the same tools as any other developer—plus some that regular developers might not even know about. They also have an in-depth knowledge of programming, machine code, and all the facets of engineering that go into building a game. That means if you don’t take precautions, they can reverse-engineer the game and use the information that they glean from this process to cheat.

Genre-Specific Risks

As mentioned, MUDs with Telnet-based front-ends are quite vulnerable to cheating, as are client software games. These are not, however, the only genres that are at risk:

  • Real-time action games are at risk from people using hardware or software to augment their own capabilities, which can happen at several levels and may not always be detectable. This might include anything from an auto-fire button on a joystick (is this really cheating? Some would say so...) on up to automated aiming and shooting software that bolts onto the client. These latter automated systems are universally agreed to be a serious threat, as are fully automated programs (bots or macros) that are capable of playing on their own.

  • Strategy games are at risk from software cracks and message interception, the intent being to lie about the in-game status of the player. In this way, the player can artificially advance his or her position in the game. This usually occurs to the detriment of everyone else; after all, their clients are playing a straight game, so they cannot possibly enjoy the advantages that the cheater has, nor can they easily detect (unless the cheating is flagrant) that cheating has taken place.

  • Games that reward repetitive in-game actions are at risk from people trying to use automated means to play more quickly, more frequently, or for longer than they are naturally able (or willing) to do. It is one thing for people to spend hours crafting a property in Second Life only to then sell it on eBay; it’s quite another for someone to build an automated software package capable of looting and pillaging with the best of them for the sole purpose of racking up enough kills to build an account that can be sold to someone to go on a killing spree. That’s just not playing a fair game.

Global Risks

In addition to these genre-based cheating strategies, there are also some more general cheating strategies that apply to games outside the strictly reflex-based action-game genre. The lack of twitch gaming does not preclude some advanced tactics for getting an illegitimate upper hand.

For example, games that rely on people being able to see what others are doing are at risk from cheaters taking another approach. Namely, they will wait until they see what everyone else has done before making their own move. That part is perfectly okay; it’s kind of like a chess strategy. The “cheating” part involves using software to spoof the other clients (and the server) into thinking that the cheater has actually made his or her move before everyone else. Then, when the moves are evaluated, the cheater comes out on top—but not by chance.

Note

Global Risks

As you saw in Chapter 7, “Improving Network Communications,” in many action games, dead reckoning is used to estimate game moves—meaning that behind the scenes, moves do happen at varying times. This places these games at risk in a similar manner as games that rely on people being able to see what others are doing.

The other side to this coin is that games that rely on people not being able to see what others are doing are also at risk. Depending on the topography used to implement the gaming model, the client might need to have this “invisible” data in order to calculate the next iteration of the game environment. The risk is that people may try to intercept this data and use it to their own ends. Again, this type of unfair advantage—known as over-the-shoulder gaming—is usually detrimental to other people’s gaming experiences.

In short, any multi-player network game that becomes more than a little bit popular is at risk from people trying to cheat. This only gets worse when the rewards for doing so are concrete rather than simply a question of personal pride—although personal pride and fame do incite people to cheat in equally large numbers for certain games. By opening up a game to many players (in an Internet environment, for example), hacks, cheats, exploits and so on are all going to surface at some point, because gamers tend to be an ingenious bunch of individuals. It’s all you can do to stay ahead of them—or at least learn to patch quickly enough they cannot cause too much disruption.

Luckily, game designers have many solutions to consider, all designed to detect, prevent, or increase the difficulty of cheating. As you will see, that is the balance that needs to be struck: Do you solve the problem at the source, attacking the cheaters themselves, or make it hard to gain any benefits from cheating?

What Are the Solutions?

The first part of any solution is to pinpoint possible loopholes in the design and fix them, thereby preventing cheating. To do this, some developers may want to turn to, well, a hacker or cheat. After all, these are the people who are most familiar with the weaknesses in games. Some will even do it for free, just because. Another way to prevent cheating is to police the game; in this way, you can at least reduce casual cheating to a minimum, because the vast majority of casual cheaters are scared of getting caught—not to mention having their account suspended. A third approach is to obscure data communications between the client and server; in this case, obfuscation capabilities are simply built into the game design, meaning that no further action on this point is needed once the game has been distributed.

Note

What Are the Solutions?

This last bit is part prevention, part detection, as a robust system will be able to detect when obscured data has been tampered with and discard the data accordingly.

So prevention at the source is part of the equation—but so is detection in the game itself. For this reason, like so many of the network multi-player implementation strategies you have seen, detection capabilities—as well as prevention mechanisms—should become part of the design as well as part of the end implementation. Note, however, that although the detection mechanism should be external to the game to prevent reverse engineering, it should not simply be bolted on at the end. Detection should happen at the server, to the extent that it is possible. Smart clients may also be part of the solution—but unless great care is taken, they will be reverse engineered and subsequently cracked if the game is popular enough. The worst thing a developer can do is underestimate the popularity of his or her own game, and thereby under-invest in anti-cheating mechanisms.

Detection Approaches

There are several ways to detect whether cheating is taking place:

  • Mechanical (i.e., network traffic)

  • Behavioral (i.e., in-game behavior transcends what ought to be possible)

  • Logical (i.e., errors are detected in data at the server side)

These three intervention points will crop up in one guise or another throughout the rest of this chapter; it ought to be possible to use any one of them as a basis for detecting cheating. To do so, however, you need to make an investment in time (i.e., implement human detection mechanisms), technology (i.e., implement automated mechanisms) or both (i.e., implement hybrid mechanisms). They all have their advantages and disadvantages.

Human Detection Approaches

Human cheating detection involves having certain players police the game from the inside. This requires that the person either play or watch for unusual patterns in the gameplay in order to spot cheats as they occur. The advantages of using human cheat detection is that doing so results in a relatively low rate false positives, coupled with the fact that when false positives—that is, when a player who has not been cheating is falsely accused of doing so—do occur, the subsequent experience is slightly less frustrating for the players involved. After all, a human can talk to the player and explain what the issue is, which will probably yield a better response than the player simply being banned by an automated process. This makes the likelihood of retaining that player after a false positive much greater.

Note

Human Detection Approaches

You’ll learn more about false positives in a moment.

Of course, the disadvantages include the fact that, as a detection approach, human detection is highly expensive in terms of time. And time, after all, is money—human time much more so than computer time. There’s also the possibility that a human will miss cheating behavior; in fact, it’s almost guaranteed.

Automated Detection Approaches

Anything that a human can do in terms of detection, a computer can usually do faster, for longer, and more reliably. As long the areas of the game in which cheating might occur are correctly identified, you can create an algorithm to spot incidences of cheating in the system. The automated system also has better access to the nuts and bolts of the game. The bits and bytes that make up the network interface, the various game values, and even the timing of events are all better processed by a computer.

The advantages of using an automated system to detect cheating are various. For a start, no humans are required, which makes it cheaper. In addition, the chances of false negatives—that is, where a cheat is not identified, or is identified as a regular player—is as close to zero as the algorithm allows; in this regard, the machine will never make a mistake. Cheaters will be caught.

Note

Automated Detection Approaches

You’ll learn more about false negatives in a moment.

Of course, the flip side of such an aggressive policy is that you may experience a higher rate of false positives. And since the system is automated, this can be hard on players; it becomes difficult to explain why a player has been banned in the middle of a winning game if all they that player has to talk to on the other side is an automated system.

Note

Automated Detection Approaches

Usually, the best detection mechanisms are those that detect automated playing (bots or macro scripts), but if the game is well designed, there’s no reason that most cheaters cannot be caught 100% of the time.

Hybrid Approaches

Most developers tend to use a hybrid approach, which can work in one of two modes:

  • Discrete threshold. This involves setting a low automated ratio of false positive/negative detection and dealing with those incidences of suspected cheating near the borders manually.

  • Layered referral. This approach scores each incidence of suspected cheating according to criteria, with humans reviewing the whole lot before action is taken.

So you can automate processes to single out potential cheats, and then use police players to follow up if there is any doubt as to whether a single instance is really cheating or not. You can then set a threshold to separate cheats about which the system is 100-percent positive from borderline cases based on your ongoing experience with the game and its cheating elements. This also implies that the detection and reinforcement process is in continuous flux, always being adapted as the game is played.

Categories of Detection Mechanics

Several detection mechanics can be implemented, regardless of your detection approach:

  • Traffic analysis. One of the easiest ways to detect mechanical cheats (such as bots) is traffic analysis. This involves examining traffic and trying to detect whether it has been tampered with. (The article “Identifying MMORPG Bots: A Traffic Analysis Approach,” by Kuan-Ta Chen, Jih-Wei Jiang, Polly Huang, Hao-Hua Chu, Chin-Laung Lie, and Wen-Chin Chen [ACE01], describes this method in detail.) Tampering can take many forms, but the most telltale signs tend to be reaction time, packet sequencing, and alterations of in-flight data. This detection mechanism, which is a purely mechanical approach, is very effective—but only up to a point.

  • Behavior analysis. This form of automated analysis is meant to detect cases in which the interface used by the player to connect to the server and other players—or to connect the player to his or her computer—has been altered to augment the player’s capabilities. These alterations might include the implementation of aiming aids that, say, enable players to shoot out of their backs, or protective devices designed to ensure that the player is never hit—even in a hail of bullets. For this type of analysis to work, the automated system must have a very good idea of how a game ought to play out—making this approach more of a design-based solution (and one that will tend to be quite resource-intensive to carry out the processing required).

  • Status analysis. Status analysis involves cross-checking the status of the player with his or her in-game actions in an attempt to see whether the client has been tampered with to improve the player’s status (for example, giving the player more money than he or she should have in an RTS, or not diminishing the player’s energy correctly in a real time–action game). Usually, the client system will have been tampered with in such a way that it incorrectly reports the state of the immediate game environment as well as the player’s status.

  • Progression analysis. This usually must be done by a human, with a flag raised by an automated process. It involves checking the progression of a player through a game over time as compared to the rest of the playing population. That is, if a particular player seems to be advancing more quickly than anyone else, he or she could be cheating. It should be noted, however, that this is typically a very subtle form of cheat, and will likely not be spotted. Besides, it doesn’t disturb the game as a whole beyond an unnatural progression—unless it can be proven that the player is not human. In that case, a too-regular progression through the game would be a clue as to the humanity of the player in question.

All of the cheats detected by these mechanics can be prevented to a certain extent, either through the design of the game or the environment in which it is played.

Prevention Versus Detection

Being able to detect when cheating occurs is useless if you don’t do anything about it. On the flip side, it is not enough to simply build in as many anti-cheating measures as possible but not invest in detection. It is simply not possible to create a game that both is cheat proof and maintains all the facets of the original design, balance, and technology that the developer envisioned. All this is to say that any measures you do implement with regard to detecting and preventing cheating will involve striking some sort of balance between the two.

On the subject of prevention, one possible approach is to make the rewards for cheating less attractive. This is difficult, however, because it usually means tampering with the very core of what makes the game fun to play. For example, anything that makes a game attractive in terms of achievement—i.e., the natural progression or advancement through the game—will become a target for cheating, as some people are naturally greedy.

Another approach to prevention is to take pains to make it as difficult as possible to actually cheat. This usually involves implementing mechanics at the design and implementation levels—which, inevitably, compromises the game’s performance and/or flexibility in some way. For example, you could move all the game logic to the server in order to ensure that the code needed to reverse-engineer the game would not be available to cheaters, but doing so would limit the sophistication of the game, as the complexity of the game environment would need to be reduced accordingly. In addition, the cost (in terms of the finished product) of doing so would weigh heavily against the benefit of having done it. Besides, cheaters could still carry out traffic analysis and would likely be able to decode for themselves how the game is put together.

If your game requires that at least some of the logic resides on the client (which is the case for most sophisticated FPS, action, and strategy games), you can at least make sure that reverse engineering doesn’t yield any clues as to how the game rules are encoded. This logic should also be applied to network traffic—in other words, exchange as little detail as possible, and encode what you do exchange in a manner that hides its true nature. Similarly, you must take steps to protect the flow of data over the network, and generally pay attention to security measures. These might include additional layers of soft security, such as key phrases, passwords, and light encryption. Note, too, that detection can produce opportunities for prevention—typically changing the client or server software in such a way to prevent the type of cheating detected in the future.

Action Versus Inaction

Once cheating has been detected, the game must decide how to deal with the culprits. Should it be overlooked? Should action be taken to sanction the cheater? If action should be taken, what kind? In the worst-case scenario, the account is immediately disabled before being reviewed, leaving the onus on the player to try to get himself or herself reinstated. Clearly, you would have to be very confident in your ability to correctly identify cheaters to take this tack. Other possibilities include allowing for a human review and, if the reviewer concludes that cheating has indeed taken place, moving to disable the account.

Instances of cheating that are considered to be less egregious—such as intentionally disconnecting to avoid a fight—might be dealt with less severely than, say, players attempting to get a leg up on others by nefarious means during gameplay. Your response to the latter might, for example, be to permanently disable the player’s account, while your response to the former may simply be to strip the player of goods, cash, or status within the game. Whatever route you choose, you must make sure that the sanction is effective.

Note

Action Versus Inaction

An innovative solution might be to allow “cheat leagues,” where cheaters can try to outdo each other. Provided players keep their cheating ways to those leagues, they might provide an outlet for some of these to let off steam. This, of course, will be predicated on the understanding that players will be permanently banned if they attempt to apply their cheating ways in the game proper.

The balance of action versus inaction is delicate. You don’t want to punish so-called “rail-gun gods”—that is, players with a seemingly unnatural aim and trigger speed. But at the same time, you need to be sure that cheating is not taking place. Otherwise, you may well find that your game becomes a battle of the cheating elements, comprised only of a cheating community. This may lock you, the developer, into an endless cycle of discovering cheating loopholes, issuing patches, and just waiting for the cheaters to find their way around the newly installed anti-cheating code.

Added to this is the possibility of a misdiagnosis. These come in two forms:

  • False positives. These are false accusations, wherein a stand-up player is identified as a cheat. False positives tend to increase in systems with very aggressive cheat-detection mechanisms, unless care is taken to establish the difference between a real positive and a false positive.

  • False negatives. These occur when a cheat is not identified, or is wrongly identified as a stand-up player. False negatives are more prevalent in systems with less robust cheat-detection mechanisms.

Of these, false positives are particularly problematic. That is, being strict with real offenders is a good thing, but punishing an innocent party is damaging to the gaming population as a whole. But false negatives pose a problem, too, in that players who continue to cheat undetected can diminish the game experience for other players. Moreover, cheaters who are not caught burn system resources illegitimately, perhaps even causing service outages, server crashes, or other problems.

Note

False negatives.

One way to reduce the number of false positives is to attack the problem of cheating by implementing preventive measures in the game’s core to reduce cheating overall. This approach will hopefully involve less in the way of in-game responses—that is, cases where some kind of sanction is required—and, by extension, reduce the number of false positives (especially if an automated system is used to identify and punish cheats).

As such, any anti-cheating strategy should use testing to play with the ratio of false positives to false negatives until a balance is struck that is workable for both the developer and the player population. Specifically, the number of false positives should be kept as close to zero as possible. (Anything above 5 percent would be considered the result of an aggressive algorithm [ACE01].)

The reason for this testing is simple: As the game becomes more popular, the cheating incidence will increase, probably beyond the capacity for the game to absorb it. In addition, the detection system must return high detection rates, with the emphasis this time on reducing the number of false negatives (i.e., cases where a player is assumed to be human when it is not). Here, anything above 95 percent is considered to be accurate [ACE01].

Note

False negatives.

This implies that the game style of every single player is subject to analysis more or less constantly, with the burden of this processing placed on the server for security reasons. Clearly, an efficient detection system will be necessary to avoid slowing down the whole game.

Hacks, Cracks, and Cheat Codes

In the pre-Internet days of gaming, “cheat code” referred to a small piece of code that could be introduced into the memory of a computer before a game was executed that would alter the game in some way. Cheat codes were shared on BBSes and in specialist magazines. Historically speaking, this practice is the forerunner of every hack and crack since, and has a special place in the development of games.

Note

Hacks, Cracks, and Cheat Codes

All games are susceptible to the introduction of cheat codes that will change the way that they operate, although the technology available to cheaters has increased exponentially since the first home-computer games (as opposed to console games) were popularized.

“Cracking” involves some kind of manipulation of a system (game or otherwise) to facilitate cheating. Crackers might crack their own client or crack the server. Either way, the implication is that some damage has been done to the system that renders it changed. “Hacking,” on the other hand, generally involves opening up a system in some way in order to obtain information. Some hackers use their skills in the pursuit of something benign, such as trying to learn from a game’s design. Others, however, share the information they obtain with crackers either for profit or in the spirit of cooperation—a kind of “honor amongst thieves” arrangement.

Note

Hacks, Cracks, and Cheat Codes

There are numerous online discussions relating to the difference between hacking and cracking. Here, we tend to distinguish them by whether the culprit simply obtains information or acts on that information.

Although a main focus for a developer is preventing hacks and cracks (as well as augmentation and the other mechanical cheats), you may also be faced with badly written (or at least incompletely tested) game software that yields holes that can be exploited by players. These are included in the category of “logic cheats”; these are usually easy to spot, as they tend to work against game rules.

How Hacks and Cracks Happen

Before any hacking or cracking can take place, the cheat needs an “in” to the game system itself; there are a number of such entry points in the system. “Locking” those entry points—protecting them from being used by hackers and crackers for ingress—is key to surviving in the network multi-player game business, especially in real time–strategy and action games, including MMORPGs. Fortunately, it is usually easy to identify and close most of these entry points—especially when players attempt to use them to do things that are outside the rules of the game. That means the detection of these holes post-development is also made easier (but should not be relied on, for reasons stated earlier—namely that it is possible to introduce data into the stream in a manner that does not rely on exploitation of these holes in the system).

If, however, a hacker or cracker does find an exploitable point of entry, your system becomes subject to the following:

Reverse Engineering

Evaluating release code to try to determine the logic behind a game or where vital data is stored is known as “reverse engineering.”

Presumably, you already understand the compile process:

Source Code → Compile → Object Code →Assemble → Machine Code

Note

Reverse Engineering

For the sake of simplicity, this assumes that the link process can be expressed as “Assemble,” which implies that the various resources, libraries, and other externally required pieces of the final system are rolled into the machine-code product.

Reverse engineering attempts to go backward in the chain. Although it is highly unlikely that the process will yield anything approaching the source code, many hackers understand the output of an optimized compiler better than the developers themselves. So even if they can’t get back to the nicely formatted source code, they can at least scan the object code (having disassembled it with a disassembler) to find out how the game works, where the important data is stored, and other vital information.

There are any number of reasons why someone might attempt reverse engineering:

  • To find the location of key data for the purpose of over-the-shoulder cheating (where the client stores values for the game environment outside the player’s own sphere of influence). This can even migrate toward changing key values so that the progress of the player is adjusted according to the cheater’s whim (the so-called authoritative client cheat category, discussed shortly). As long as the client software can be made to believe that the data values are legitimate, then the cheater’s own world view will permeate through the game environment and become truth.

  • To find loopholes in the game logic that can be exploited—for example, weaknesses in the underlying programming that might be used to win challenges. One such logical fault was found in a popular online game, where it became apparent that a player could teleport things into other players with disastrous results. (Of course, you’re already aware that testing is a good way to trap these kinds of glitches.)

  • To devise mathematical/logical solutions to puzzles revolving around how various things are calculated or the location of key objects in the game universe.

  • To track back to network data that can then be modified in-flight in order to manipulate the natural progression of the game. If someone knows where key data is stored, he or she can find out how it is accessed and what it looks like just before or during transmission. (Note that in order to make the most of this approach, there must be something between the client and the server to process the in-flight data. The information on its own is not particularly useful.)

Of course, some reverse engineering is fairly benign. In many cases, people do it simply to try to get information that would help players be more successful. In the single-player world, this is reasonably common, as is trying to change values to help the local game. It is only when the information is subsequently applied to a network game with more at stake that it becomes an issue.

Physical Cheats

Physical cheats are usually facilitated by a machine that sits between the client and server, its sole purpose being to intercept packet streams at various levels and modify them depending on information derived from the in-game environment. Theoretically, this machine could be acting as a network relay proxy or even something between the man machine interface (MMI) and the game system. Any kind of mechanical auto-fire style button would fit into this category. Other tools include the following:

  • More advanced systems of auto-play (as long as they are not solely software based).

  • Automatic playing mechanisms that revolve around using screen sensing by peeking into video memory and testing values of pixels. That information can then be used to help the player control his or her gaming experience, augmenting his or her natural ability with logic.

  • Advanced information packages that use the data exchanged between clients, and between the client and the server, to overlay information on the screen to which the player should not be privy. Even something as basic as a map overlay can mean the difference between success and failure in an online game.

Note

Physical Cheats

Most physical cheats apply only in cases where reflex time is paramount.

Many physical cheats can be detected using some of the techniques listed earlier. For example, you can measure behavioral reaction times to pinpoint cases where the reactions seem to happen too quickly after the event that caused them. If you use additional logic to determine the player’s line of sight at the same time, you can use the reaction time and environmental data together to weed out cheats. Testing and balancing will then enable you to determine where the natural line can be drawn between expert players and automated assistance.

Logical Cheats

In addition to physical cheats, there are logical cheats, which can affect any game—not just those that rely on split-second reflexes. A logical cheat uses the game’s design against itself, perhaps by directly intervening or maybe by finding a loophole in the game’s design.

Note

Logical Cheats

No third-party programs need be running in order for the logical cheats to work—although some third-party software will be necessary (i.e., for writing to memory whilst the game is in session).

Games in which the client is assumed to be correct and informs the server of the progression of the game are particularly at risk, a key problem being the fact that the client doesn’t know it’s been hacked, and the server can’t really tell because it does not have access to the data. In other words, although the data in the memory locations managed by the client is assumed to be correct, this data can in fact be modified by a hacker/cracker either to demote other players’ positions or beef up the cheater’s own. This is just one example of a logical cheat; you’ll see many more later on, when we discuss kinds of cheating that have been seen in the wild.

Spoofing and Spying

In addition to the straight cheating techniques discussed previously, there are also some clever techniques that could be used to help a player—even if it might not be classified as cheating per se:

  • Spoofing. Normally, spoofing refers to making the system believe that a player is someone else. Here, however, we use it to also cover instances when the client is making the system believe that there is a real person behind a virtual in-game one. This occurs when a pseudo player appears on a separate account, and is used purely to garner information, and to display that information for the real players’s use. Examples of the information conveyed might be a detailed map with locations of other players or some AI used to predict events and the locations of other players. Because the pseudo player, which plays automatically, exists simply as an information-gathering entity, it doesn’t matter if it is repeatedly killed and has to be reincarnated. It need only play at a level that makes it look human.

  • Spying. This involves spying on data packets and using the information therein to track other players, even if they can’t be seen in-game. This is a very stealthy approach that needs no actual in-game intervention by another tool. It’s just watching, after all, and is nearly impossible to detect. For this to work, the spy’s game client needs data from all the other clients in order to play out the game—which is also sometimes necessary due to jitter and other network issues. In other words, the very things you use to deal with the problems associated with network gaming, as discussed in Chapter 7, can be used against you.

Clearly, the only thing you can do to combat these stealthier types of cheating is protect your game—and hope that you do enough for long enough that it doesn’t negatively affect the game. (By this I mean, of course, affect sales of the game or game subscriptions in a bad way.) Protecting the game can mean anything from obscuring data that is exchanged between clients to obfuscating the code base such that casual hackers cannot derive any information from it. Other protections are also possible, with the focus always being to ensure that it is as difficult as possible for hackers to do their damage.

Types of Cheats

In “How to Hurt the Hackers” [GAMA01], Matt Pritchard divides cheating into six categories:

  • Reflex augmentation. This type of cheating occurs when the player augments his or her skills with a proxy or other third-party program. Auto-aiming, mapping, and other programs designed to give an unfair advantage fall into this classification.

  • Authoritative clients. This is where client software relays false updates to the server and other clients, and is assumed to be the authority on that data. Because the game logic is considered sacred, the server and other clients have no reason to doubt it.

  • Information exposure. This classification includes cases where the player can see—or has put himself or herself in a position to see—information that should remain hidden. All kinds of data is flying around the system, and it’s your job to make sure that it cannot be used against the game.

  • Compromised servers. In this classification are cases where the server has been hacked (either from within or without). This is quite severe and must be taken very seriously; it could very well happen if precautions are not taken to prevent it.

  • Bugs and design loopholes. These are exploitable problems in the design or implementation of the game, either at the client side or on the server. Usually, these are uncovered by hacking or automated playing, but can be uncovered during testing in much the same way.

  • Environmental weaknesses. In this classification are issues that become apparent only when the game is running, and may be detected only as a function of another facet of the network gaming paradigm—e.g., lag causing game-state suspension and queuing of multiple cancel requests for the same initial action in Age of Empires [GAMA01].

For the purposes of this discussion—and to look at possible solutions to the root causes of these problems (i.e., data communication and hacking code)—these categories can be further grouped to describe the cheating behavior:

  • Exploits. Here, the code of the game is not changed, but players manage to gain an advantage using loopholes or other weaknesses.

  • Augmentation. Here, the player or game is augmented by other software.

  • Cracking. Here, the game code is compromised in order to obtain an advantage.

You can try to factor out cheating that you can prevent by paying attention to three key aspects of software creation:

  • Rigorous testing

  • Design

  • Run-time detection

That is to say, anything that falls into the exploits category—bugs and design loopholes, environmental weaknesses, or perhaps information exposure—can potentially be dealt with by good testing practices. By a similar token, cheats arising from cracking—say, compromised servers and perhaps authoritative clients—need to be dealt with at the design level. Finally, cheats involving augmentation—i.e., authoritative clients or reflex augmentation—are countered using run-time detection (although there are things that should be done at the design level to prevent repeat occurrences). You may, in time, produce your own classification system, vital for tracking potential opportunities for cheating in the game that you are putting together.

I’ve introduced a paradigm that makes sense to me—that is, one that focuses on exploits, augmentation, and cracking—but that might seem to be too strict to apply to Pritchard’s classifications. But the definitions are quite fluid, and will change from game to game, as will the roles of the various actors and facilitators in the system that make cheating possible.

Note

Cracking.

Some of Pritchard’s classifications—information exposure, for example—describe facilitators to cheats more than active cheats in themselves. To deal with this, we might have created another classification that was more directly based on cause and effect. For example, suppose we tried to address a situation where the information exchange is too transparent, meaning players could use the information to create an authoritative client hack or for reflex augmentation. The resulting category might then encompass everything to do with data exchange, and solutions would need to be found for every possible cheat within that category.

Exploits

Exploits include bugs and design loopholes, where the code is examined to find ways in which the game logic can be fooled into allowing actions that are not normally possible. For example, someone might discover that it is possible to teleport into locations, including characters, and use that information to destroy in-game personae by, say, teleporting a bomb into them as opposed to it appearing next to them, which would give them the chance to run away. The bug in this case is treating players as locations (rooms) in their own right—handy for inventory management (you can put things “into” the player), but disastrous if those locations are known to other players.

Note

Exploits

The availability of a single-player version of an otherwise identical multi-player game will give players plenty of time to find out where these loopholes might be.

Related to bugs and design loopholes are environmental weaknesses, which rely on finding holes in the design of the game environment. For example, as noted in Pritchard’s “How to Hurt the Hackers,” there are cases in which players have been caught hovering between two server zones, knowing their enemies can’t cross from one zone to the other (NPC controlled), and taking pot shots at them. Information exposure also falls into this category, as it involves the exploitation of a weak network transmission protocol or coding that has not been created to render data non-transparent.

The more you can do to mask data, the better, because a simple exploit can result in something more immediately damaging: augmentation of the player’s natural abilities.

Augmentation

This category includes reflex augmentation, which is, as you will remember, a simple extension of the player’s own natural ability. (Note that without information exposure, reflex augmentation would not be possible; in this way, these two classifications are intimately linked.) The category also includes authoritative clients, which augment the game data and forward it into the network as if it were the true status of the in-game entities. Of course, that data is changed in such a way that it masks the true state of the local player (usually) with respect to the game environment.

Cracking

Like the augmentation category, this category, too, includes authoritative clients, where the client is cracked such that it no longer follows strict game logic, instead generating results that are either possible but highly unlikely, or downright impossible. If there is no cross-reference to check whether the data is feasible, then the player might not really need to play at all, managing his fake game position with a cracked client. This is fairly unlikely, however—as is the possibility that there will be compromised servers (also in this category) on the game network. After all, one would hope, in modern systems, that security was sufficiently tight to prevent a direct hacking and cracking attack on the game servers.

That said, this does not preclude games’ vulnerability to other forms of cracking, where the very fabric of the implementation is damaged through intentional misuse. For example, suppose some casual hacking of an online RPG game revealed to the hacker that all the descriptions are stored in a MySQL database with a PHP front-end. Given the well-known vulnerabilities in both SQL and PHP, a hacker might well introduce small scripts, which would be executed by the server and result in untold damage (the so-called SQL “injection” technique, for example). The bottom line is, once a hacker has exposed the relevant interfaces, he or she can use it to gain a competitive advantage in much the same way as any regular exploit or augmentation cheat.

Note

Cracking

Of course, all of these require a certain level of information exposure. Therefore, keeping data opaque is again proven to be paramount to maintaining an anti-cheat gaming service.

Bots and Automated Playing

An entirely separate category of cheating is described by the common term “bot.” A bot, or script/macro, is an automated player that relies on scripted commands and a dose of AI and in-game knowledge to carry out tasks as if it were a real player. Players use bots—which might be, for example, a program that sends keystroke information to the game, thereby emulating the actions of a player—for many different reasons: some to gather information, others to build up accounts with large resources (which can then be sold to people who want to cheat by getting a head start in the game).

Some people wonder whether bots really matter, and where the dangers actually are. The way I see it, if a player can defraud the system by using a bot, then they do matter, and the dangers are clear. Besides, excessive automated playing can be a drain on system resources, especially since bots have one clear advantage over humans: They don’t get tired.

Note

Bots and Automated Playing

Dangers exist in many modern games (Unreal Tournament for example), where open scripting mechanisms are built in specifically to support bots, thereby revealing to bot creators how they might go about constructing their own to be used from a playing perspective rather than, as is common, an NPC perspective. In some games, the creation of these bots is encouraged—even necessary. But letting people build bots, and giving them information about how to do so, does rather open up the system to exploitation if not managed carefully.

The only real way to deal with unwanted bots is to detect them—typically through network monitoring, with the “tells” being extended up-time, fast response times, repetitive actions, and the like, as well as through in-game logic—and shut them down. Prevention is not really feasible; after all, it is unlikely that you’ll want to cripple the system by removing scripting entirely.

Communication Layer Cheats

Any time a game sends data out over or receives data from the network, the game system as a whole (including all connected clients) is at risk. In fact, the communications layer is the most vulnerable, as it potentially exposes the most data to cheating by:

  • Altering data in transit

  • Adding data to the flow

  • Changing the flow of data physically

The most danger is present when the data stream can be changed without requiring that the client software be changed, as this becomes impossible to detect.

Data-in-Transit Cheats

A data-in-transit cheat involves changing the data being sent by the client to the server (often by inserting rogue packets of data between legitimate packets to change their meaning) or examining incoming data. An auto-aim proxy, for example, makes use of both, examining incoming data and inserting packets to help the player hold his or her aim on an opponent. Specifically, the proxy software might use the incoming data to determine the location of the nearest opponent and then check the direction in which the player is firing. Based on this, the proxy will then insert packets before the fire command to focus the weapon such that it is aiming at the chosen target (here, the nearest opponent). When the other clients process the incoming data, they perform the aiming adjustment and shoot, reporting that the target has been hit. (This is unless, of course, some kind of spoofing is in place, by which it is reported by the targeted player’s client that the player, in fact, moved just before the shot was fired, thereby avoiding it completely. The game then becomes a battle between the efficiency of two proxy gaming clients.)

Note

Data-in-Transit Cheats

In addition to handling data-in-transit cheats occurring on the communication layer, you must also address those data-in-transit cheats involving the authentication layer. These include more traditional hacking and account-hijacking cheats—which, while irritating from those concerned, are outside the scope of this book as they deal more with security than competitive advantage.

Lookahead and Update Dropping

“Lookahead” is roughly defined as the ability of a player to see events that seem to happen in the future from the point of view of the client, or a player’s ability to project his or her own moves into the future as if the player had the ability to see other players’ moves before they are made. This can be achieved in different ways:

  • By waiting until all moves have been made before making one’s own move, pretending to be on a very slow connection (i.e., no response packets). This approach might make use of a technique known as update dropping, in which a proxy system drops data as if it were a slow or unreliable interface.

  • By changing ongoing data to reflect an earlier posting time.

Note

Lookahead and Update Dropping

Naturally, both lookahead and update dropping require an intimate knowledge of how data exchange occurs on the network.

These work because of a system for managing updates known as “dead reckoning.” As you learned in Chapter 7, dead reckoning is a way to project the known movement data into the future in order to combat the effects of jitter and latency on the network. The trouble with dead reckoning is that, with every time-step that passes without a checkpoint of the data (i.e., without real data coming in), reality and perception potentially diverge. It is only when the packets finally arrive that the local copy of the game knows what the “real” reality is. In the absence of that data, the game plays out using its best guess of the state of the game environment.

Obviously, at some point, the dead reckoning will be so hopelessly out of date that the system will have to take drastic action. This could involve one or a combination of the following:

  • Disconnect the player

  • Continue playing as a local NPC bot

  • Continue playing as a server-based NPC bot

The most common way to use lookahead to cheat is to spoof the client’s latency to fool a dead-reckoning system by time-stamping its own moves in the past. In this way, the cheating system can wait until it sees the honest players moves before making a move of its own—whilst appearing to have made the move earlier. The other players might not even notice that this has taken place; it will probably just seem as if they are playing against a particularly gifted (almost clairvoyant) player.

A similar cheat is to exploit a system that waits for a number of packets to be dropped before classifying a client as disconnected. In these cases, the cheater need only forcefully drop his or her packets—which are usually required to inform the other clients and the server that the player is still connected—until such a time as he or she has seen all the other moves, and then send out his or her own update. In doing so, the player simulates a connection experiencing severe jitter/latency, tricking the system into believing that it is simply taking a long time to receive, process, and respond to update packets.

Intentional Disconnections

The final type of communication-layer cheat is one that I alluded to in Chapter 7: Intentional disconnection. There are two sides to dealing with this type of cheat:

  • Determining whether the disconnection was intentional. The disconnection should be scored according to the likelihood of it being intentional, what the player has to lose by not disconnecting, and prevailing network conditions. Complicating things is the fact that declining network conditions may have contributed to the predicament of the player—meaning that the player either felt that he or she had to disconnect, or that he or she was eventually disconnected by the client because network conditions had deteriorated to a certain degree. But if network conditions are otherwise stable, and if the player would stand to avoid in-game penalties by disconnecting, then you can probably say that the disconnection was intentional.

  • Making the punishment fit the crime. You should take action that reflects what the player has gained by intentionally disconnecting during an in-game exchange. What you want to avoid is a case where a player disconnects in the middle of a battle and is returned to his or her last “safe” point, with his or her in-game properties restored. Otherwise, you remove the risk associated with intentional disconnections, thereby rendering the game much less enjoyable for everyone concerned.

Note

Making the punishment fit the crime.

Note that the issues surrounding intentional disconnections really only apply to action games. With strategy and other game types, such a quick fix wouldn’t help—for example, in Civilization, where the game has to play out from start to end, there not being any real persistent link between game sessions.

Solutions to Communication Layer Cheats

In order to prevent cheating that involves taking advantage of the data-exchange model or the actual data exchanged between the clients and the server, you should attempt to put in place some mechanisms for discarding data that you judge to have been tampered with. At the same time, you can prevent the cheating from taking place at all by making sure that a casual hacker cannot extract meaning from the exchanges in the first place. At the core of the solution, however, is ensuring that the data stream remains unaffected.

Packet Serialization

You first encountered the idea of packet serialization—where, typically, packets are numbered and sent in sequential order—in Chapter 7 as a way to prevent data loss. Because many communications layer cheats involve tampering with data that is reminiscent of real data loss (refer to the lookahead cheats outlined previously), packet serialization can be a good way to combat them.

The key here is being able to detect whether data is missing or has been inserted. Packet serialization enables the server to do just that. It also helps to identify out-of-sequence packets, especially if a suitable input and output buffering system is used (Chapter 7 explains buffers more fully). That said, it’s relatively easy for someone to figure out which serial numbers factor into a series of packets—meaning a cheater can fiddle with the values whenever he or she wants to insert or remove a packet.

This assumes, however, that the packets are numbered sequentially. That is, you might combat this by assigning a pseudo-random number to each packet, derived from an algorithm generated using the contents of the packet (timestamp, data, etc.) as well as its place in a queue of packets. Alternatively, you might serialize bursts of packets, with one packet containing a header, one containing a trailer, and a hash calculated across all packet identifiers—thereby building a value that can be quickly validated without needing to examine each identifier in turn. In this way, disturbances of the stream can be detected by the server or client. This will, however, require that the pipeline be at least wide enough to consume all the packets in a burst, which can introduce jitter, which must then be combated using dead reckoning (again, seen in Chapter 7).

The Lockstep Protocol

The paper “Cheat-Proofing Dead Reckoned Multiplayer Games” [EECSD01] isolates several strategies to combat cheating in dead-reckoning systems—including one called the “lockstep protocol.” Although this protocol is quite involved—and the actual implementation of it falls beyond the scope of this book—its usefulness as an anti-cheating mechanism requires that the theory behind it be detailed here.

In the basic lockstep protocol, at a given cue—usually when all packets have been received—client systems will evaluate the state of the game environment as one. In this way, problems of dead reckoning are immediately solved, because every player must wait until moves from all other players arrive before the next frame can be calculated [EECSD01]. The problem with this approach is that the game runs at the speed of the slowest link—and if latency is a factor, this could be quite slow indeed (as you saw in Chapter 7).

You can, however, use these synchronization delays to your advantage by employing something called the “pipelined lockstep protocol,” which enables the system to send out frames before the frames from other players are received. Frames sent will contain only the data pertaining to the client doing the sending, and will represent the player’s commitment to a move—hopefully in absence of knowledge of the other moves—at just the right time so as to smooth over network latency.

The drawback to this approach is that it does not protect against late-commit cheats, as clients can wait until all the other players’ moves have been received before committing to their own move. The so-called adaptive pipeline (AP) protocol, however, combats this by adjusting the lockstepping to match the frame rate so that it is close to the natural frame rate. In other words, AP tries to combat late-commit cheats by establishing a frame rate that seems reasonable and assuming that anything outside of that is an attempt to defraud the system. (This does mean, however, that you must use traffic analysis to spot occurrences of cheating, as it is still a possible—although very difficult and unreliable—way to do so.)

Another interesting solution is the sliding pipeline (SP) protocol, which adjusts the so-called pipeline depth to reflect the prevailing network conditions. The distinction between the SP and AP protocols is that in the SP protocol, there is a buffer that holds moves while the pipeline size is adjusted.

Using one or a combination of these protocols, you can minimize cheats that rely on exploiting the dead-reckoning algorithms used to combat network problems. In order to combat other cheating mechanisms involving the actual data transferred, however, you would also want to secure the data—discussed next.

Data-Level Solutions

First and foremost, you must provide a solution to prevent authoritative client cheating—specifically, by making sure that data cannot be tampered with once the client has sent it out. Simple hashing and subsequent encryption of the hash value can prevent this, as long as the keys are hard to determine. In this way, you can also reduce the impact of encryption by passing over a hash value only once rather encrypting/decrypting the whole packet.

Of course, this doesn’t prevent someone from looking at the values, using them to determine what is going on in the game environment, and subsequently cheat. To address this, you can also present data in a variable way. For example, you can constantly change the layout, the data names, or even the meaning of the data in a randomly variable way. Something as simple as adding a pseudo-random offset value to all positional data can go a long way toward foiling many cheats.

Logic Layer Solutions

You can do a lot at the logic layer to make sure that cheating is made more difficult, as well as allow for detection. These solutions, however, must be designed in rather than added as an afterthought. Many of these solutions also apply to other kinds of games. For example, non-networked games could use logic-layer solutions to try to detect when a player has introduced a cheating mechanism.

These techniques also help to prevent other kinds of cheats, such as mechanical cheats—for example, keyboard trapping and auto target selection. These cheats are different from those that are introduced in the logic layer itself (i.e., cheats that involve changing the client or the client data), but they can be combated by the logic layer.

These cheats require a combination of game-universe knowledge and interaction. If you can remove one side of the equation—the game-universe knowledge—you can tackle the problem head-on. To that end, rather than allowing game-universe information, such as the positions of enemies, fly around in the communication layer, thereby making things easy for hackers and cheaters, it is better to transmit status information balanced against some kind of checkpointing to avoid ad-hoc detection. The checkpointing needs to be robust enough to be able to track status data with respect to the entire game environment, including the logic layer. Additionally, as pointed out in the Gamasutra article “How to Hurt the Hackers” [GAMA01], you must also use AI to try to spot cheating when it takes place. In other words, if you assume that the logic layer will be compromised, there should be some kind of cross check to make sure that you detect this as soon as is possible.

As noted in Chapter 7, part of the problem is that local clients make decisions to account for jitter and lag. These decisions aren’t just at the level of dead reckoning, but are also actual in-game decisions that relate to the processing of game universe data (i.e., authoritative client cheats, where the client is assumed to be correct even when the logic layer is compromised). The logic layer is all-important in these cases. To prevent the client (or the server) from being hacked in such a way as to give an individual a competitive advantage (i.e., cheat), you must make sure that the code and data provided cannot be easily used to reverse engineer the game. Perhaps the best way to do so is to use code obfuscation to combat information exposure.

Code Obfuscation in the Logic Layer

Because information exposure is at the root of many hacks, bots, and other cheats, it is an important part of the anti-cheating equation. As mentioned earlier in this chapter, the purpose of hacking is to reveal places in memory (during run-time), places on the disk (level files), or even places on the network that are used to store information vital to the running of the game session. If that data is easy to decipher, it will be easy to crack and spoof.

One way to prevent this is through the use of code obfuscation—that is, taking things with logical, easy-to-remember (and identify) names, and making them much more difficult to remember and identify.

There are many ways in which code can be intentionally obfuscated:

  • Using illogical, impossible-to-identify names

  • Dynamically changing names and/or locations

  • A combination of these

Employing any of these techniques ought to make it more difficult for a hacker to find the data—meaning the hacker will not be able to give it to a cracker or use it to alter the natural path of the game to his or her own advantage (or at least everyone else’s disadvantage).

Before you continue, it bears mentioning that there are inherent downsides to using code obfuscation in these ways. First, the result is very hard to debug; it is difficult to trace back the meaning from the code, even for the developer. Second, the resulting code will likely be slower to execute (especially using dynamically changing names or locations for data), as the machine has to spend time managing the process. Finally, even if all these forms of obfuscation are applied, the code is—in addition to being prone to error—not completely secure. There is always a lynch pin that holds it together; once found, that pin can be used to pull it apart. Testing for that point can be time consuming; the developer must be sure that it won’t be more trouble than it’s worth, even before starting out. The purpose of this discussion is to help you make that judgment call.

Static Code Obfuscation

The first technique is to change type and variable names statically—in other words, to make them less readable by assigning unique, but possibly random, names or by following a scheme that seems to have no underlying meaning.

So, for example, a very readable set of location data might be specified as follows:

struct PLAYER_LOCATION {
  int x_position, y_position, z_position;
};
// declarations
PLAYER_LOCATION * oPlayerLocationTable; // player one is at [0]
// example function calls
void AllocatePlayerLocationTable ( PLAYER_LOCATION oLocTab ) {
// code to do allocation
}
PLAYER_LOCATION * GetPlayerLocation ( int nPlayerID,
PLAYER_LOCATION * oLocTab ) {
// return the player location of nPlayerID
}
// etc.

From this, it would be very easy to find out, once compiled, where the player table is located in memory. Since the code contains a symbol table, a hacker would be able to trace backward from the variable name, data type, and even the function names that are tasked to do the work.

So a basic, first-level obfuscation might take this code and, using an automated tracking and allocation solution (discussed momentarily), allocate names that are less readily identified with specific parts of the game. This can be done at the source-code level or using an external tool that obfuscates names at the linking cycle. The end result might look like the following:

struct AAA-001 {
  int AAA-002, AAA-003, AAA-004;
};
// declarations
AAA-001 * AAA-005; // player one is at [0]
// example function calls
void AAA-006 ( AAA-001 AAA-007 ) {
// code to do allocation
}
AAA-001 * AAA-008 ( int AAA-009, AAA-001 * AAA-007 ) {
// return the player location of nPlayerID
}
// etc.

The lookup table that gave rise to the preceding would then look as follows:

PLAYER_LOCATION                      AAA-001
x_position                           AAA-002
y_position                           AAA-003
z_position                           AAA-004
oPlayerLocationTable                 AAA-005
AllocatePlayerLocationTable          AAA-006
oLocTab                              AAA-007
GetPlayerLocation                    AAA-008
nPlayerID                            AAA-009

There is, however, a downside to this technique: It yields really unreadable code. Not to mention, when debugging, it becomes hard to trace back from the disassembled code to the source. You could try to get around this by only obfuscating at the end—but what happens if, for some reason, the act of obfuscation itself introduces errors? The answer to that question is twofold. One, it becomes very hard to distinguish between errors due to obfuscation and errors in the underlying code. Two, it requires double the amount of testing at the end of a development schedule that is likely behind anyway. The result might just be that it is dropped at the first sign of difficulty because, after all, the rest of the game works.

In addition, a hacker simply needs to observe the byte levels of data to begin spotting patterns that will yield its use. So no matter how good the obfuscation is, if a hacker has access to this level of detail, a dynamic solution is needed.

Dynamic Code Obfuscation

You can obfuscate data at the logic layer before it is passed to the network communications layer to make sure that the data is not easily deciphered. To do so, you can use a dynamic scheme for changing the names and offsets of data. Hence, a variable name and value that might normally be represented as

player_x:100

can be obfuscated through the addition of a simple random offset. To avoid patterns creeping in (i.e., repetition of _ and : characters), that offset must also be dynamic with reference to the position of the character in the packet of data as a whole. In this way, you can create a stream of seemingly meaningless data for very little processing overhead. And provided that you are using a scheme, you can always get back to the original (using a code-wheel approach, for example),

Note

Dynamic Code Obfuscation

A typical networked first person shooter usually sends and receives thousands of bytes per second. Subsequently, we cannot spend too much time with encryption, so obfuscation provides a very easy solution.

This same kind of obfuscation can also be done with level files, which would technically make it harder for hacking to take place locally. Whether this would be worth the effort, however, depends entirely on the kind of game being developed. Games that are predominately about teamwork within a relatively simple level file would not benefit overly from obfuscation. In contrast, games built around the level file in such a way that the level file itself is an important part of the challenge (traps, puzzles, etc.) are clearly going to benefit more from adequately obfuscated level files.

Dynamic obfuscation of code and data location is also a possibility. This includes moving data (and even code) around in memory, thereby making it difficult for a hacker to track. Even if a hacker were to try to fiddle with the data, he or she might well be fiddling with data that is either no longer there or now another part of the system entirely. Disadvantages to using this approach include a possible performance hit from the constant reallocation of memory blocks, and the possibility of introducing loopholes in the allocation process that could be exploited by cheats.

At design and development time, the source code should be readable (respecting software engineering practices), which makes it more easily maintainable. So for source code, you might have a preference to compile-time (i.e., at the time that the code is created for the game) or run-time obfuscation (i.e., whilst the game is running). In the latter case, the variable names and values (and possibly function names) are changed according to a scheme that has been designed into the software.

Possible Pitfalls

Naturally, there are things that can go wrong. For example, it is no good having a sophisticated run-time obfuscation strategy if the code doing the obfuscation is not, itself, obfuscated. In addition, there are the aforementioned dangers of the obfuscation causing run-time errors. In the final analysis, the game developer will likely have to attack this problem with a two prong solution—run-time and compile-time and/or design-time—if obfuscation is actually required. For any games where the central server is the authority, of course, none of these approaches are needed. Even a game such as that, however, is not immune to attacks from bots.

Identifying Bots

Bots are discussed here as a logic-layer cheat—although they actually occur somewhere between the communication layer and logic layer, as does the detection of bots. For this reason, the solution must look at both the behavior and the network components involved.

The main issue is, as noted in “Identifying MMORPG Bots: A Traffic Analysis Approach” [ACE01]:

“Identifying whether or not a character is controlled by a bot is difficult, since a bot-controlled character obeys the game rules completely.”

Note

Identifying Bots

It is worth noting that “Identifying MMORPG Bots: A Traffic Analysis Approach” [ACE01] was one of the first (if not the first) papers to address bot detection using traffic analysis. This came at a time (2006) when the standard practice was to dialog with the bots as a way to determine whether they were human. Clearly a more effective and efficient approach was needed.

Solutions to these kinds of cheats are expressed in “Identifying MMORPG Bots: A Traffic Analysis Approach” [ACE01] and involve measuring various traffic metrics because certain key indicators in the traffic profile usually point to an automated system. The idea is to try to build a profile of normal traffic and to compare it with the actual traffic in the hopes that an automated system will be caught out. Luckily, bots have some key identifying characteristics:

  • Reaction time

  • Unfailing memory

  • Inability to dialog

Note

Identifying Bots

Without the possibility of comparison, one can only use generalizations—which might increase the number of false positives (or false negatives) in the detection algorithm.

First, you must make sure you can collect traces (i.e., reports of network activity, each line relating to a unit of data transfer) so that analysis can be done during the testing/development process. That way, you can get a handle on what regular play, tested play, and test cycles using your own bots look like—which makes detection in the end product much more reliable and easy to implement.

One of the key measurements, as identified in “Identifying MMORPG Bots: A Traffic Analysis Approach” [ACE01], is release timing, or how long it takes to issue the next command following the last command. The theory, borne out by analysis, is that because human players use a mouse or keyboard, their reaction times vary as the action increases. In contrast, bots use a decision loop and periodic timers—meaning that when you look at their response times coupled with data-packet arrivals, it is much more regular. On top of that, it scales, so increases in activity don’t change the response times—or, if they do, it’s because the bot recognizes that it has to reply more quickly to be ready for the next cycle.

For the purposes of discovering whether a bot is playing, the actual measurements of interest are as follows:

  • Prompt response. The time elapsed between when the packet leaves the server and the response arrives at the server is unfeasibly brief.

  • Regularity in response times. Response times are too regular to be human;

  • Traffic burstiness. The amount of traffic in a given time span should be smoother than when compared with a player because the algorithms are artificial.

In addition, “Identifying MMORPG Bots: A Traffic Analysis Approach” [ACE01] noted that human players automatically adapt to network problems that change the pace of the game. That is, as latency begins to creep in, human players will naturally generate in-game actions in response to things that are happening at a gentler pace. A bot, on the other hand (unless very cleverly written) remains crisply responsive—in this case totally unnecessarily, as the latency means that there is no need for the bot to be ready immediately for the next cycle.

Actually identifying a bot involves performing a variety of tests to determine whether the observed peaks and troughs in the various timing graphs are significantly different from what might be considered to be the norm. Most of these tests require statistical analysis of observed behavior to ascertain the chances that a specific traffic profile can be identified as a bot (or, conversely, as definitely not a bot). The tests are ongoing, and the traffic profiles have to be dynamic so that the weight of experience can be brought to bear on the analysis. When the system can do that, it ought to be able to detect with a great deal of accuracy the presence of bots in the game network.

References

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.17.75.43