I intend to search opcodes in specific memory area in process's dump.
I want to have some conditions while searching.
like: $$><<>script.wds #call 00400000 L? 01000000
for(00400000 ~ 01000000)
{
// this condition is if argument's opcode which is address is not in this area
.if(arg1's opcode !in 00400000 ~ 01000000)
.print arg1
}
your query is unclear do you want to do something like this
running the above script by providing three arguments you can search for any instruction in the range you provide the argument 1 is call so i want to search for call instructions arg 2 is an expression therefor windbg will be evaluated to an address like 0x12340000 arg 3 again is an expression evaluated to size result as follows
I'm not exactly sure if I understood what you need, but I think it is similar to the following.
Create a script which does what you want, using pseudo registers, e.g.
Set up the "parameters" in pseudo registers
Then run the script:
Considering the whole task, I'd not recommend doing that in plain WinDbg and use some higher level abstraction such as PyKD, because
!address
es only that arePAGE_EXECUTE
You can use a combination of
#
,.foreach
and$spat
.Lets say you want to find the few first
call
opcodes innotepad!WinMain
. You could do something like this:And now the explanation.
# call notepad!WinMain L20
searches for the string "call" in the disassembly on the specified range. This is the output:The
.foreach (var {cmd}) {commands}
executes cmd, splits the output at whitespaces, and executes {commands} once for each of the tokens it got with "var" being replaced with that token.Without the
.if
we'd get something like:Finally we add the
.if
to check whether our token starts with "notepad!" and ends with ":". Note that we have to test for the colon at the end. Otherwise we might get "notepad!SkipProgramName" and "notepad!NPInit". Even testing for "notepad!WinMain*" isn't enough, since it might be the target of local jumps.Now, if you want to pass this address to any command, you have to get rid of the colon at the end of the addr alias the
.foreach
command created. I'm not sure there's even a way to do it, so we do one last trick. Every time we find and addr that fits the pattern we set a flag, and at every iteration we check the flag. If the flag is raised, we use the current token. Since the output of#
is of the formThe token following the symbol that matches our pattern is a clean address.
For example, the following command disassembles two opcode for each
call
found:(The pseudo-register
$t0
is the flag.)And now, after this horror is done I join Thomas in suggesting you use PyKd if you want to go even a further beyond that.
The mere fact that we can do this using WinDbg's awful awful scripting language doesn't mean that we should.