• Welcome to Valhalla Legends Archive.
 

WinDBG not reading the call stack correctly?

Started by Stwong, August 17, 2004, 10:14 AM

Previous topic - Next topic

Stwong

So, I'm trying to find out what is calling a certain function in Starcraft. (The function that adds minerals to the SCV.  No, I'm not being noobish and trying to make a mineral hack, it's for a friend that wants a different mineral count per run in his mod.)

At any rate, I've identified the function that does so, found the variable I want to watch, and have breakpointed that function with WinDbg with bp 0x422DA0.  Breakpoint works fine, breaks the execution after I enter 'g' and make the SCV start mining.

Great, so I've successfully breakpointed the function.  Time to find out what called it.

I type in 'k' to check the callstack for the return address to go to.  "It promptly warns me that Stack unwind information is not available, following frames may be wrong."  I would second that motion, since telling WinDBG to 'Go Up' (gu) causes it to die prettily.  WinDBG cannot write to the memory there, or read from it.  Not only that, but the address 0x007F8000 has never seemed like a place that a call would be, especially since most of SC's code is quite a bit before.  (Nearly all of the functions I've disassembled were in 4XXXXX, most of them in the 40XXXX-42XXXX range...)

At any rate, popping the disassembler open to this location just yields question marks in the window.

At any rate, the function I'm trying to trace up is a CALL'ed function, I'm pretty sure.  It starts by pushing a register it wants to use, ends with it popping it back off the stack, and then returning, while doing some other things. (Mainly, setting the amount of minerals the miner is holding to 8, or less if the pile was just finished.)

Thanks for bothering to read that, if you reached this point :P

Kp

Quote from: Stwong on August 17, 2004, 10:14 AMSo, I'm trying to find out what is calling a certain function in Starcraft. (The function that adds minerals to the SCV.  No, I'm not being noobish and trying to make a mineral hack, it's for a friend that wants a different mineral count per run in his mod.)

At any rate, I've identified the function that does so, found the variable I want to watch, and have breakpointed that function with WinDbg with bp 0x422DA0.  Breakpoint works fine, breaks the execution after I enter 'g' and make the SCV start mining.

Great, so I've successfully breakpointed the function.  Time to find out what called it.

I type in 'k' to check the callstack for the return address to go to.  "It promptly warns me that Stack unwind information is not available, following frames may be wrong."  I would second that motion, since telling WinDBG to 'Go Up' (gu) causes it to die prettily.  WinDBG cannot write to the memory there, or read from it.  Not only that, but the address 0x007F8000 has never seemed like a place that a call would be, especially since most of SC's code is quite a bit before.  (Nearly all of the functions I've disassembled were in 4XXXXX, most of them in the 40XXXX-42XXXX range...)

At any rate, popping the disassembler open to this location just yields question marks in the window.

At any rate, the function I'm trying to trace up is a CALL'ed function, I'm pretty sure.  It starts by pushing a register it wants to use, ends with it popping it back off the stack, and then returning, while doing some other things. (Mainly, setting the amount of minerals the miner is holding to 8, or less if the pile was just finished.)

Thanks for bothering to read that, if you reached this point :P

Assuming you know what offset in the unit structure records that 8, why not just put a write-access breakpoint on that field and let Starcraft lead you right to it? :)  Syntax is "ba w1 <addr>", where addr is the byte you want to break-on-write.  Use w2 for 16bit values, w4 for 32bit.  iirc, windbg docs warn that you need to get the size right or it won't break, but I've never checked that.

To address the more general problem: the compiler probably didn't bother putting a frame pointer for this function, so you won't be able to "go up".  However, all is not lost.  You just can't get the debugger to help you out on this one.  Dump the stack contents and manually find the return address, then jump there in the disassembly to see if you're right.  If not, keep reading the stack for other candidates.  If you don't find anything on the stack that looks like the caller, the calling function may have transferred control to the current location as its last act.  In that case, the compiler will sometimes prefer a long jump to a call.  If that's happened, you're out of luck with the debugger, and will need to use some other method of binary analysis to figure from where control is coming.
[19:20:23] (BotNet) <[vL]Kp> Any idiot can make a bot with CSB, and many do!

Stwong

#2
As for the write access breakpoint--that's how I got to the point that I'm at.  In this code, esp points to some strange structure that is reloaded with different data quite frequently--the reason I'm trying to go up is to find out where this data is loaded for this particular function.

Breakpointing that data doesn't work, due to the amount of functions it's accessed from per second (something in the range of 30-50 while idle, I counted up to 250 with basic orders.  it seems to have something to do with orders.)

As for other methods of binary analysis--any hints on where to start with those?

EDIT: The address I'm doing this backtrace for is usually 0x12FExx...  In another post, on the Advanced Programming board, Skywing mentions a similar address as being stack memory.  I'm going to look into that.

EDIT 2: Yes, it does seem to be the stack.  It boggles me that they don't push the value off the stack, but instead copy it into a register using mov and the esp pointer...  That would explain why this data region gets read/written to really often, and often by push/pops :D

EDIT 3: And, with ESP being the top of the stack, right there is a pointer to the return address.  I feel kinda dumb now.  Issue resolved :)

Adron

Surprising that I never saw this post before...

Anyway, just to clarify for future readers: Stwong seems to have been looking at all the locals stored on the stack. That being the only structure esp typically points to, and that is accessed from many different functions per second :)