WinDBG: Execute du Command on first arg of top stack automatically - windbg

I have a breakpoint on some source code set up.
Each time the break point is triggered I execute two commands:
0:000> kb 1
# RetAddr : Args to Child : Call Site
00 00007ffa`a05db848 : 00007ffa`a061ac98 00007ffa`b3135ba1 000002a8`32f20000 000002a8`32f20000 : KERNELBASE!GetEnvironmentVariableW
Pick the first argument address 00007ffa a061ac98 and display it via
0:000> du 00007ffa`a061ac98
00007ffa`a061ac98 "InstallRoot"
Now basically the break point gets hit everytime and I always have to manually run two commands and a manual copy paste of an address.
Is there a more automatic way?
I've tried dx but this does not work for me, as I am missing the parameters
0:000> dx -r3 Debugger.Sessions.First().Processes.First().Threads.First().Stack.Frames[0]
Debugger.Sessions.First().Processes.First().Threads.First().Stack.Frames[0] : KERNELBASE!GetEnvironmentVariableW [Switch To]
LocalVariables : Unexpected failure to dereference object
Parameters : Unexpected failure to dereference object
Attributes
InstructionOffset : 0x7ffab0835240
ReturnOffset : 0x7ffaa05db848
FrameOffset : 0xce79ffee90
StackOffset : 0xce79ffee98
FuncTableEntry : 0x0
Virtual : 1
FrameNumber : 0x0
Nor does getting the parameters work
0:000> dx -r3 Debugger.Sessions.First().Processes.First().Threads.First().Stack.Frames[0].Parameters
Error: Wrong Parameter. (0x80070057)
A hint on how I could extract Arg[0] from top frame and display it more automatically would be great!
Note: I basically want to execute this command each time the break point hits. Maybe there is a better way for this.

Found it: The first argument is in ebx in my case. So
du ebx does the trick!

Related

How to display the address of the function in WinDBG for .fnret command?

I need to get the address of the function required by .fnret command in WinDBG.
For example, I want to get the information about return value of apphelp!ApphelpCheckRunApp function.
First, I set a breakpoint on this function:
bp apphelp!ApphelpCheckRunApp
Then I'm continuing the execution, until it breaks on that function.
After breaking, I'm executing .fnret [Address] command.
I already tried to use the 77b345d5 address displayed on the breakpoint:
Breakpoint 0 hit
eax=77b345d5 ebx=7ed320f5 ecx=7ffac000 edx=7c886920 esi=7ffac000 edi=00000018
eip=77b345d5 esp=0378ce90 ebp=0378d108 iopl=0 nv up ei pl nz ac po cy
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000213
appHelp!ApphelpCheckRunApp:
77b345d5 8bff mov edi,edi
but that seems to be not what I need, because I get the following error:
^ Unknown or unsupported return type in '.fnret 77b345d5'
Also I used return address 7c818cdf of this function from call stack (got via kb command):
ChildEBP RetAddr Args to Child
0283ce8c 7c818cdf 00000474 046bb7d0 00000000 appHelp!ApphelpCheckRunApp
but it leads me to the same error.
Which WinDBG command I should use for that and which return address it will display (in case it isn't displayed yet on breakpoint)? Will it then properly work for .fnret or .fnret /s commands? Unfortunately, there are no any examples of using them on MSDN, only the documentation.
Hoping on your help. Thanks in advance.
.fnret is only useful if you have private pdb
it is not useful if you have public pdb because it needs to retrieve the type information
here is a sample usage on a compiled code with private pdb
0:000> x /t /v /f myst!towlower
prv func 00007ff6`74ba5f84 7 <function> myst!towlower (unsigned short)
0:000> x /t /v /f myst!toupper
prv func 00007ff6`74b91b10 2a <function> myst!toupper (int)
0:000> .fnret myst!towlower
myst!towlower (00007ff6`74ba5f84) = unsigned short 1
0:000> .fnret myst!toupper
myst!toupper (00007ff6`74b91b10) = int 0n1
error on a known function which returns a HANDLE using public stripped pdb
0:000> .fnret KERNELBASE!CreateFileA
^ Unknown or unsupported return type in '.fnret KERNELBASE!CreateFileA'
success on a system file with private pdb
it casts the forced return value dumped in #rax as a typed return with value of a function with type information
a system file with prrivate pdb
0:000> .printf "%y\n" , 0x00000001`800bace0 ; an arbitrary function
ole32!ToUnicode (00000001`800bace0)
0:000> .printf "%mu\n" , 00000001`8014c17a ; an arbitrary wide string
guageErrorPointerą“‚Š
0:000> r rax = 00000001`8014c17a the $retreg is populated with an address of wide string
0:000> .fnret 0x00000001`800bace0 << fnret casts the $retreg as wide string and prints the resulting widestring
ole32!ToUnicode (00000001`800bace0) = wchar_t * 0x00000001`8014c17a
"guageErrorPointer???"
OK, that command is indeed not helpful at all when using public PDBs.
I found better solution here: How to get return value from a function in windbg?.
It is possible to get the memory address of return value by viewing eax/rax register on x86/x64 appropriately, using r command (since it always is stored there). After breakpoint, I'm just typing r eax on x86 or r rax on x64. Output will be look like this:
eax=[Address]
Then, I'm displaying a value of received memory address via d* (dd, du etc. displaying data types commands), like this:
du [Address]
After looking at the output, it becomes understandable which data is returned, and its data type also (at least in most of cases).
But to understand first, which data type is used, I'm trying the different combinations of display memory commands and display referenced memory commands.

change style code function VScode time optimisation while coding

my goal is change a function to a format where the return value of the function is treated :
For example ; treating a the function scanf()
Return value of scanf : The value EOF is returned if the end of input is reached before
either the first successful conversion or a matching failure occurs.
EOF is also returned if a read error occurs, in which case the error
indicator for the stream (see ferror(3)) is set, and errno is set to
indicate the error.
Thus
scanf("%d\n",&i);
will be change to
#define RVAL(exp) do {if ((exp) == -1) { perror (#exp); exit(1); }} while (0)
...
RVAL(scanf("%d\n",&i));
Thus I want this to be done quickly means :
so what i do is look for occurences of "scanf" and replace it with "RVAL(scanf"
but the problem is i have to add another right parentheses
Can this be done fast ? using a techniques ? or a style ? where each whenever I enter scanf(); its replaced witch rval(scanf());
If you don't have many ) in your format string you can use a regex with (scanf([^)]*)); and replace with rval(\1);
*see comment

Encounter with a strange Mask initialization Command

So in one of the mask in the model i came across an initialization command that i don't understand.
The logic is for an SR Flip Flop. That latches the output.
It has 1 parameter that takes in the initial state for output 1(Output is o and o(bar)).
Which has the following properties:
Name: MaskParam1
Value: 0
Type: Edit
Evaluate: True
Tunable: True
The command is written in the Initialization tab of the Mask Editor.
ini = (#1~=0);
The first thing that came to my mind was anonymous function handle, that returns value of the parameter. In this case would be 0.
So as (0 ~=0) = 0hence the initial output of SR will be 0.
When i type the following in matlab:
ini = (#1~=0);
I get an error of unexpected matlab expression.
So I tried another thing. Considering as the Parameter is refering to the masked parameter so if we take a variable:
x = 0;
% The default value for the mask parameter
ini = (#x~=0);
This will give an error that
Error: "x" was previously used as a variable, conflicting with its use here as the name of a function or command.
So my question is ini
ini = (#1~=0)
a function or a variable??enter code here

Dump out all Args to Child on a given stack

How do I dump out all Args to Child for my current thread stack e.g. I want to do a command like du on the args for every frame in the current stack. Like du ebp+<1st 4 args> on all frames.
IMHO it's not very easy to do in WinDbg itself, but I can recommend PyKd to solve this task. Make sure you have Python installed in the correct bitness (same bitness as WinDbg that you want to use).
0:000> .symfix
0:000> .reload
0:000> .load E:\...\pykd\0.3.0.27\x86\pykd.dll
Use pykd.pyd if there's no pykd.dll.
0:000> !py
>>> s = getStack()
>>> for f in s:
... for p in range(1,4):
... print("%016X" % (ptrPtr(f.sp + p*ptrSize())))
...
>>> exit()
s is the stack of the current thread.
for f in s loops over all frames.
p will be the parameters where 0 would be the return address and 1 to 4 are the parameters as displayed by kb.
p*ptrSize() calculates the correct offset with respect to the bitness
f.sp gives you the stack pointer of the current frame
ptrPtr() reads pointer-sized (bitness aware) data from memory
"%016X" % n formats the number in hex
exit() gets you out of the interactive console
Now that you have all the parameters, you can also dump their values as strings. You can try loadWStr() of PyKd. Here's a complete script:
from pykd import *
s = getStack()
for f in s:
for p in range(1,4):
paramaddr = f.sp + p*ptrSize()
string = loadWStr(paramaddr)
print(string)
If you want to apply it to all threads, run it like this:
0:000> ~*e !py string.py

Windbg pseudoregister expansion

I am trying to automate a device driver's debug session in Windows XP with Windbg. My device has an "index" register and a "data" register, both memory mapped. The index register must be filled with the internal register's index, and the value can be read from the data register.
So, the followind Windbg command prints correctly the value of the internel register 0x4C:
!ed [uc] 0xfa000000 0x4c; !dd [uc] 0xfa000004 L1
Now I would like to dump a range of internal registers, but it seems that the alias expansion doesn't work as expected in the !ed command. I am trying this cycle:
.for (r $t0=0; #$t0<0x100; r $t0=#$t0+1) { !ed [uc] 0xfa000000 #$t0; !dd [uc] 0xfa000004 L1 }
but it seems that the !ed command is ignored, as if #$t0 was expanded in an empty string.
Tried "$t0", "#$t0", "${t0}" and "#${t0}", but without success. What am I doing wrong?
Yes it seems !ed does not evaluate its arguments like other commands. You need to evaluate them beforehand, for instance with an alias, like this:
.for (r $t0=0; #$t0<0x100; r $t0=#$t0+1) { as /x val #$t0 ; .block {!ed [uc] 0xfa000000 ${val} ; !dd [uc] 0xfa000004 L1 } }