Ok ebp: This is generated by the compiler around every function. It's a pretty standard mechanism in any program and has to do with passing parameters into functions. Are you familiar with how the parameters are passed on the stack?
Say I'm foo(), and I want to call thingy(), passing it x and y, so it can do it's thingy on them and let me know the result.
Just for an example:
Code:
void foo(void)
{
...
thingy(x, y);
...
do_really_cool_thing_with_x; // this is awesome!
do_fairly_cool_thing_with_y; // need this later for bar()
...
return;
}
int thingy(int x, int y)
{
x += y;
x = x * 2;
return x;
}
X and Y would normally be passed from foo() to thingy() on the stack, like this:
Code:
push x // store "x" for thingy()
push y // store "y" for thingy()
call thingy // do it!
add esp, 8 // take "x" and "y" back off the stack
"thingy" is supposed to set "eax" to it's return value (X in this example) before it returns.
So now we're in thingy() and the stack looks like this:
Code:
return_address [i](points back to foo())[/i]
value_of_y
value_of_x
...
Since thingy() can't pop y and x off the stack without first popping return_address, which would mean it then had no way to get back to foo(), it will instead access value_of_y and value_of_x by "peeking" back on the stack with a reference like [esp+4] or [esp+8], which looks at value_of_y or value_of_x respectively.
Well, the problem with that is, what if thingy() needed to use
PUSH or
POP for some reason. Say thingy() needed to call some other function, and pass
it X and Y. The instant thingy() calls
PUSH, it's going to screw up the relative positions of X and Y, and now [esp+4] points at the return address, not Y anymore. To avoid the confusing nightmare of having to keep track of all that, most compilers reserve ebp to be used as a sort of second stack pointer. At entry to every function the first thing they do is freeze the position of esp into ebp. Then they can use the stack as the stack like normal, and if they ever need to access their arguments, they can do it easily just by offsetting from ebp (so instead of [esp+4], they can now access Y through [ebp+4], which is the exact same thing except that it won't be screwed up if a PUSH or whatever moves esp around during thingy()). The reason they have to PUSH it first then POP it before return, is so thingy() doesn't screw up ebp for foo(), since foo() is also counting on always being to access it's parameters through ebp.
Oh, and every time Windows does a task switch ("pre-empts" a process for multitasking, momentarily giving CPU time to another running process) the kernel saves all the registers, then when it comes back to that program, it sets them back as they were before execution, so the program doesn't even know it had left. Since every thread effectively gets it's own set of registers, CS couldn't possibly screw up ebp for any other programs. But it could screw up ebp royally for itself, which is why the compiler is so attentive about saving ebp on entry to every function. In fact, it's so "paranoid" about it that sometimes it will even do it on functions that never touch ebp, are only 3 or 4 instructions long, and don't take any parameters.
Number II
I don't know. BUT, I don't think it should be very hard to do at all. What program are you using for debugging? This is how I would find it:
We need an "entry point" or "foot in the door" to get us into the general vicinity of code that has to do with inventory. To do this, one approach I use often if I've never reached that area of a program before is to use a GameShark-like cheat-finding program (I use a program called GameShock) to locate a memory address used by the code we're interested in, then setting a memory breakpoint on access/write to that address (usually Write yields more interesting results).
GameShock works by process of elimination: you tell it you want to find an "unknown value", and it scans the memory of your program and takes a snapshot of the entire memory contents. Then you go back to your program, and you do something that you think will say, make the interesting variable bigger. Go back to GameShock and push "Increased", and now every memory address that hasn't gotten bigger is dropped from the list. Do this around 10 or so times mixing it up with Increased and Decreased and you'll often zero right in on the variable you're looking for.
Once you think you've found it tell GameShock you want to set it as a "cheat" and just freeze the variable at whatever value it's currently at. Go back to CS and make sure that the thing you were interested in, is now screwed up (because it can't write to it's variable any more). If this works, turn the "cheat" off and copy the memory address GameShock found, set a Write breakpoint on it in your debugger, and you'll be taken straight to the section you want. Finding that, just read up and down through the assembly, maybe experiment a little, till you understand it good enough to know how to change whatever you want.
In this case, the thing I would be looking for in GameShock is the position of the "cursor", or which item you have selected. Because it's easily moveable around (incrementing and decrementing it's variable), it should be much easier to find then directly going after the flashing state.
As for the flashing state, knowing Pixel, I would guess, that this works based on a timer, which is incremented every frame, and the "bright" or "dim" is decided by taking either the modulus of this timer, or right-shifting it by around 3 or 4 bits then testing the least-significant bit of the result.
It's also possible that every time the timer reaches around 5 or 6, it toggles the frame, then resets itself. In this case, the most likely method of toggling the flashy state is adding 1 to the current frame, then setting it to zero if it becomes greater than 1 (he had a macro that did this). It's also possible to do a toggle by XOR'ing the current value with 1, or by subtracting it from 1, but while they're popular with some programmers, I haven't seen Pixel use those latter methods very often.