I am trying to reverse game called Assault Cube where I am gonna be making game hacks for. I using Ollydbg to reverse though I have no theoretical understanding of asm at all. I just follow online videos and just guess and play around to see what results I get.

Anyways, I have found the gun function by placing breakpoints. Now I want to look inside that to find automatic shoot and no recoil. To find those I just nop one by one and see how it affects. But I have a problem I also included a picture for you guy to reference. When I nop addresses and it seems to be successful giving the results I need like automatic fire and no recoil. But when I write my hack in Visual Studio and apply the nops, compile and run. The game will crash. This is because I don’t know how to determine what is the correct start and end of the function, though nopping a set of addresses still gave me my result but when compiled it will crash.

Long story short, how do I know the exact start and finish of the function even when nopping gives the result making you think you found it but once compiled you end up finding out it the right place but not the exactly right start/finish. I hope you understand what I mean. Please look at the picture I included. Thanks. enter image description here


It sounds to me like your problem is the code in VS, not what you've found through reversing. The beginning of the function there doesn't seem to matter in accordance to what you're trying to do. Correct me if I'm wrong, but it sounds to me like you're thinking you have to find your way to the beginning of the function so that you can then figure out how far into the function you need to go to change what you want to change.

That's an understandable train of thought given your level of experience. (If that's what you're thinking, that is; I'm making an assumption to craft a reply based on.)

First of all, what you want to do is luckily very easy (relatively speaking) since all you want to do is directly change bytes. Given that, what you generally need to do is find a direct reference to the memory address that the bytes/instructions of interest are stored in. Let's break down what that means for you.

Look at the line you have highlighted in the screenshot:

00463716 75 09 JNZ SHORT ac_clien.00463721

00463716: This is a memory address. It's where your bytes of interest are stored. This is where you'll want to find your way to in your program.

75 09 JNZ SHORT ac_clien.00463721: 75 09 and JNZ SHORT ac_clien.00463721 are the same thing. The bytes, 75 09, are hexadecimal. They are a concise representation of binary sequences that the CPU understands. Why not just show the binary numbers directly instead of in hexadecimal? Well, let's look at what 75 09 is in binary: 111010100001001.

Now imagine seeing all binary in that column in OllyDbg, as opposed to hexadecimal. Not only is it unwieldy, but with some instructions, the numbers would take up a ridiculous amount of space in the row. Also, it's much easier for you, the human reader, to know what byte 75 means as opposed to bits 1110101, which is what the CPU ultimately understands.

The assembly instruction that you see in English (JNZ SHORT ac_clien.00463721) is an even further distillation for us to be able to easily read the instruction. You see that and you know it says "jump a short distance to memory address ac_clien.00463721 if the zero flag is not set".

So, in the case of the instruction we're working with here, bits 1110101 is the same value as hex 75 is the same thing as JNZ. They're just different ways of representing the same thing, mostly for our sake so we don't have to try to read a bunch of 1s and 0s.

Bearing that in mind, you know that changing JNZ to JMP gives you automatic weapon fire. Thus, your program needs to find the memory address that byte is stored in (which, per the screenshot, is 463716, but may change upon restart). Then your program needs to write a new byte that you want. The byte you want for JMP in this case is EB.

Now you have everything you need for coding up an application. This is where my help stops and your external research begins, because now you're in the territory of forward engineering (the reverse engineering process is completed). Are you trying to code your hack in C, C++, Visual C++, C#, or otherwise? Your choice of language will directly inform the approach you take for programmatically finding the game's process, opening it, finding its base address, then writing your byte to the correct offset therefrom.

Where 'X' is your programming language of choice, questions like, "How do I find the base address of a game or program in X"; "How do I find the process ID of a game or program in X"; "How do I write bytes to a memory address in X", and so forth should lead you down the right path.

Finally, since you're hacking Assault Cube, I recommend signing up over on the Guided Hacking forum and inquiring there. They've used that game specifically as a target for countless tutorials of theirs over the years, and there are a lot of very experienced programmers who can help you through the basics, including learning about all the things you don't even know to ask about right now.

Hope that helps!


Important note: Reverse engineering of proprietary products can be legal issue, make sure you covered on it.

Regarding your question:

  1. Download IDA Free 7.0 https://www.hex-rays.com/products/ida/support/download_freeware.shtml
  2. Load binary you try to debug in Olly in IDA and go to the specific address you see on the picture. [Press G and enter 0x463016 for example]
  3. Let's hope it's not obfuscated and/or apply ant other techniques - you will find yourself in address near the jnz instruction
  4. If not already inside the function [you should see instructions in some white cubical], then press Space button to switch to graph mode.
  5. Scroll up to the beginning of the function - here you have your address [put cursor on first instruction and press Space again to switch back to disassembly mode] - this will be the start of the function

  6. There are multiple ways to get to the end of function from position on the screenshot:

    6.1 Scroll down to the ret instruction in graph mode [there can be more than one!] - this will be the end of the function [or there may be multiple function exits via call or jmp instructions as well]

    6.2 Another way to learn the end of function is Ctrl + F9 in Olly [if i remember correctly] - it will break on first ret.

    6.3 Another option was described here: Jump back to the caller

And if you really want to RE - learn some disassembly tools together with debuggers, this will help you understand the logic :)

Good Luck.


  • IF ANYONE WOULD LIKE TO GIVE MORE TIPS PLEASE FEEL FREE. Please keep it basic and simple to understand as I know not much. – Learner Sep 5 '18 at 3:39

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.