Set a code breakpoint at the point where the stack frame is established and another one at the point where your target value gets used (and hence must have been written already).
In the condition script for the first breakpoint you can add a hardware write breakpoint for your target location; its absolute address can be computed at that point because you have the actual values of ESP and EBP. The second breakpoint is for deleting that hardware breakpoint.
In the condition script for the hardware breakpoint you can do whatever you want: check for a specific value being written, check surrounding values etc.
Note: CheatEngine was written expressly for tasks like that. You might get results quicker and more easily if you get CheatEngine instead of trying to make sense of IDAs meagerly documented - and often quite bizarre - interfaces.
Here's a rudimentary script that you can adapt by modifying the test in target_check_()
and adapting the stack offset in set_target_breakpoint_()
. The values there are from a quick test that I did to ensure that the code works. This is for IDA 6.7; it will definitely not work with the free IDA (v5.0).
#include "idc.idc"
static main ()
{
set_helper_breakpoints_(LocByName("test_ufuncs_t"), 0);
}
static target_check_ (ea)
{
auto e;
try
{
Message("DbgDword(%x): %x @ EIP %x\n", ea, DbgDword(ea), EIP);
return DbgDword(ea) == 0x410A10;
}
catch (e) { Message("error: %s\n", e.description); }
return 0;
}
static set_target_breakpoint_ (term_bpt)
{
auto target_ea = ESP - 0x70;
Message("target_ea %a\n", target_ea);
SetBptCndEx(term_bpt, form("DelBpt(0x%x) & 0", target_ea), 0);
AddBptEx(target_ea, 4, BPT_WRITE);
SetBptCndEx(target_ea, form("target_check_(0x%x)", target_ea), 0);
return 0;
}
static set_helper_breakpoints_ (init_bpt, term_bpt)
{
if (term_bpt <= 0)
term_bpt = FindCode(GetFunctionAttr(init_bpt, FUNCATTR_END), SEARCH_UP);
Message("set_helper_breakpoints(): %s %s\n", GetFuncOffset(init_bpt), GetFuncOffset(term_bpt));
AddBptEx(init_bpt, 0, BPT_DEFAULT);
AddBptEx(term_bpt, 0, BPT_DEFAULT);
SetBptCndEx(init_bpt, form("set_target_breakpoint_(0x%x)", term_bpt), 0);
SetBptCndEx(term_bpt, "0", 0);
}