[Windbg Script] Disassembling Routines and Searching for Instructions
Sometimes you cannot avoid reading the disassembled code to look for a specific assembly instruction. You may want to see if a particular function is doing some specific operation, using some specific register, or calling other functions.
You can do that using the disassembling window or using a dead listing and looking for specific instructions; however, it is error prone and it might take time depending on the volume of disassembled code you need to analyze.
Here’s where this script enters! It allows you to search for specific instructions from a specific function. It shows you every time the instruction appears and all call instructions. You can click on those call instructions and see the called function and all call instructions it has by navigating the call tree.
I hope it helps you to save as much time as it’s helped me, especially when you need to dig out at disassembled code to look for specific instructions. J
Screenshots:
Now let's select a method to disassembly:
Running the script using the method as argument and looking for a specific instruction:
Now we have all occurrences for the specific instruction and we can see the called routines. Clicking on those should show the disassembled code:
Source code for DIG_DISASM.TXT:
$$
$$ =============================================================================
$$ Show all occurrences of a specific assembly command that appears inside a function
$$ body.
$$ Also shows all 'call' commands and enables the user to drill down the information.
$$
$$ Compatibility: Win32.
$$
$$ Usage: $$a<myscripts\DIG_DISASM.TXT addressOrFunctionName assemblyCommand
$$
$$ Example: $$a<myscripts\DIG_DISASM.TXT certcli!CAOIDGetLdapURL xor
$$ $$a<myscripts\DIG_DISASM.TXT 751d8caf xor
$$ $$a<myscripts\DIG_DISASM.TXT 751d8caf "mov dword ptr [ebx],eax" <-- Four spaces between mov and dword.
$$
$$ Attention: Do NOT use $$>a<, use $$a< to run the script.
$$
$$ Roberto Alexis Farah
$$ Blog: https://blogs.msdn.com/debuggingtoolbox/
$$
$$ All my scripts are provided "AS IS" with no warranties, and confer no rights.
$$
$$ =============================================================================
$$
.printf "\nATTENTION! When using commands that requires spaces put 4 spaces betwen them, like:\nmyscripts\\DIG_DISASM.TXT 751d8cff \"push dword ptr [ebp-4]\"\n\n"
.block{.if((0 = ${/d:$arg1}) | (0 = ${/d:$arg2})){.printf /D "<b>\n\n\nYou need to provide the address or function name and the assembly command (mnemonic).\n\nExamples:\n\nDIG_DISASM.TXT 751d8caf xor\nDIG_DISASM.TXT MyApp!MyFunc xor\nDIG_DISASM.TXT MyApp!MyFunc \"push eax\"</b> -- 4 spaces to separate\n\n"}.else{.block{.printf /D "\n\n\n<b>Occurrences of pattern</b> ${$arg2}<b> in function</b> ${$arg1}<b>:</b>\n\n";.shell -i - -ci "uf ${$arg1}" FIND "${$arg2}"};.block{.printf /D "<b>\n\nAll </b>call<b> instructions for this function. Click on the hyperlinks below to navigate:</b>\n\n";uf /c /D ${$arg1}}}}
Comments
Anonymous
February 24, 2008
PingBack from http://www.secure-software-engineering.com/2008/02/24/windbg-script-disassembling-routines-and-searching-for-instructions/Anonymous
September 18, 2008
I'm trying to compare the ${$arg1} to Win32 for instance and define a breakpoint as in: .if{${$arg1}==Win32) { bp ReadFile ".printf "ReadFile(handle=%N, bytes=%N)", poi(esp+4), poi(esp+c); gc;" } For some reason, the comparison fails. Can you advise me how to rewrite the condition?Anonymous
September 18, 2008
First, there's a typo in your code: .if{ should be replaced for .if( Since you're trying to evaluate a string you can use this approach: if(0 == $sicmp("${$arg1}", "Win32")) { ... } Note: I haven't tested the code above but it should work. This is the approach I use here: http://blogs.msdn.com/debuggingtoolbox/archive/2007/04/19/windbg-script-extracting-performance-monitor-counters-from-net-application.aspx Let me know if you still have problems. ThanksAnonymous
September 18, 2008
Thanks, it works.