Polar Life Capsule
Can't put <ML+ inside a weapon

Load up Cave Story with OllyDbg. Use Ctrl+G to get to address 40482D (this address is inside the Polar Star code). Now, you should see, directly after the address you just jumped to, an instruction that stores -1000 into the memory location [ECX+18]. It turns out that [ECX+18] is a variable that controls the horizontal speed of a bullet when shot out of the polar star.
Address   Instruction
0040482D  MOV ECX,DWORD PTR SS:[EBP+8]     ;store number located at address EBP+8 into register ECX.
00404830  MOV DWORD PTR DS:[ECX+18],-1000  ;stores -1000 into [ECX+18] (which controls horizontal speed)
00404837  JMP SHORT 0040485B               ;jump somewhere else
Pretend that the "PTR SS:", "PTR DS:" and "SHORT" aren't really there, it's just some extra stuff that you don't need to worry about.

Just notice that -1000 is being put into [ECX+18], then the program jumps somewhere to take care of some other stuff. Eventually, the polar star bullet is created and given a velocity of -1000 horizontally. The 3 lines of code you see above are executed whenever you fire the polar star in the left direction.

Now, we can replace some of this code to make the polar star do something different when we shoot it left. But we can't just replace any old code. The JMP 0040485B definitely needs to stay there, because otherwise the program doesn't jump to the right place to finish off the process of managing bullet behavior. We certainly do want it to jump to the right place, otherwise weird stuff might happen if it starts executing instructions that we don't want it to execute.

Let's make it so that your max health is set to 96 when you shoot the polar star left. Remember from a previous lesson that MOV DWORD [49E6D0],60 is the instruction that will set Quote's health to 96. Double click on the instruction MOV ECX,DWORD PTR SS:[EBP+8] at address 40482D. Now replace the whole thing with MOV DWORD [49E6D0],60. Make sure "keep size" is NOT checked, since we actually do want to overwrite the next instruction. From now on, you can leave "keep size" unchecked.

Polar Life Capsule Hack

After doing that, save your changes and close OllyDbg. When you open up Cave Story and fire the polar star left, you'll notice that your max life will be a lot higher. Get to a health refill and you'll see that it is indeed 96. But when you shoot the polar star left, the bullet does not move anymore. This is because we erased the instruction that set -1000 as the horizontal speed of the bullet.

Undoing a Hack
Let's try something different. We are going to return the polar star to its original form. Go to address 40482D and edit the maxlife instruction there. Replace it with MOV ECX,DWORD [EBP+8]. This will prepare ECX so that -1000 can be stored as the horizontal speed, which is [ECX+18]. You'll also see some NOPs appear at address 404830 after you click Assemble. Double-click on the NOP at 404830 and replace it with MOV DWORD [ECX+18],-1000. Remember to make sure that "keep size" isn't checked, so that you can overwrite the other NOPs below the first NOP. Now select both of the two red instructions at the same time (both should be highlighted in gray) and copy them to executable.

Close OllyDbg, test the Polar Star, and you'll see that it's back to normal, since we put back the first two instructions that were originally there.

Diagonal Bullets
Now, a 3rd hack shall be done. We didn't mess with JMP SHORT 0040485B in the first hack because we didn't know what it would do. But let's try to remove it now.

Open up OllyDbg once more. Go to 404837, which is the address for the JMP SHORT 0040485B. Right click on that instruction, go to Edit > Fill with NOPs. Instead of jumping to address 40485B, the code will do nothing, since NOP is the instruction that does nothing. Copy the 2 NOPs that appear back to the executable, then close OllyDbg. Test the hack.

Diagonal Bullets

Well, that's interesting. Whenever you shoot left, the bullets move diagonally now. Why?

Of course, the answer lies in the ASM code:

Shoot left code

With Diagonal bullet hack:
Shoot up and left code

You can see that by removing the first JMP SHORT 0040485B causes the "shoot-left" code to creep into the "shoot-up" code. So whenever you shoot left, it's like shooting up and left at the same time. Therefore, a diagonal bullet is created with both a horizontal and a vertical velocity.

Previous Lesson: Pointers and Memory
Next Lesson: The Stack
Table of Contents