Why does windbg title stack with childebp and args to child - windbg

I know this may sound nit-picky, but I want to know if there is a reason for these semantics.
Child to me means those are the things it will pass to the function it is about to call, however if you break on function name, then a given record will already exist and will not change. That record shows what that function received from its parent.
Lets say that I break on wmain and step in a few lines.
windbg will report:
# ChildEBP RetAddr Args to Child
00 005dfeb8 009e138b 00000001 00ac9bc0 00acfac8 ASMTests!wmain+0x19
Now those values wont change.
When I enter the next function DoBuf0, they don't change so they are not actually the args to the child, They are the args received from the parent.
Eg:
My wmain passes "buf0" as second argument to DoBuf0
# ChildEBP RetAddr Args to Child
00 005dfe0c 009e1131 005dfe34 009e218c 005dfe74 ASMTests!DoBuf0
01 005dfeb8 009e138b 00000001 00ac9bc0 00acfac8 ASMTests!wmain+0x91
0:000:x86> da 009e218c
009e218c "buf0"
They are the args the parent (wmain) passed to the child (DoBuf0), But they are NOT displayed on the Parents line, they are displayed on the childs. Wouldn't it make more sense to just call them Args from parent? In the case above args to Child implicates that DoBuf0 will be passing them to ITs child.
Thanks

Child to me means those are the things it will pass to the function it
is about to call
How could the window show things that have not happened yet? Do you expect some sort of speculative execution simulation? A "child" is something that has been called, and the call has left evidence data on the stack.
Quote from the WinDbg help
Raw args displays the first three parameters that are passed to the
function. On an x86-based processor, this display includes the first
three parameters that are passed to the function ("Args to Child").
Addrs displays various frame-related addresses. On an x86-based
processor, this display includes the base pointer for the stack frame
("ChildEBP") and the return address ("RetAddr").

Related

is there an abnormal way to terminate a child process to get certain outputs in this code?

i'm new to operating systems and i found this code , and i don't understand why certain outputs like : abc , we can't get
suppose we have this code in c :
int main()
{
if(fork()==0)
printf("a");
else
{
printf("b");
waitpid(-1);
}
printf("c");
return 0;
}
waitpid() waits for a child process to terminate.
can the child process be terminated in abnormal way ? so that we can have this outputs : abc, bc ?
according to at least the linux manpage for fork:
RETURN VALUE
On success, the PID of the child process is returned in the parent, and
0 is returned in the child. On failure, -1 is returned in the parent,
no child process is created, and errno is set appropriately.
so if your child program isn't ever created the entire output will be c for the parent process and nothing for the child process, because it never came to be.
Also it is possible that the parent process is killed before it can output a, or c, then you'll only get the child's output, bc. or maybe the parent is killed before it can even fork! there are lots of possibilities and with good timing (and some calls to the sleep function inbetween) you could probably reproduce them.

Understanding STMicro Reset Handler example code for STM32

The example Reset Handler code provided by STMicro for STM32 (in my case it is for STM32H753) is the following:
Reset_Handler:
ldr sp, =_estack
movs r1, #0
b LoopCopyDataInit
...
I don't understand the first instruction, that sets the stack pointer.
Indeed the Vector Table is defined as follows:
This means that the Stack Pointer is set by the CPU from the first word in the Vector Table. This is confirmed by debug (when breaking before executing the very first instruction of the Reset Handler, the SP is set properly).
Is there a reason to keep this instruction ldr sp, =_estack in thr Reset Handler ?
The Vector table contains on its first position the initial stack address. But the programmer might want to set another value to it or set up the double stack.
In the linker script you have:
_estack = address ;
and in the very simple startup file:
g_pfnVectors:
.word _estack
.word Reset_Handler
but you can change those values to be different or the ResetHandler is called from the bootloader. Then you need to set the stack pointer to the correct value.

How many total number of processes are there?

Yesterday, i had a interview and i was asked this question of code snippet using fork() .
void main()
{............
for (int k=1;k<=10;k++)
{
pid[k]=fork();
if(!pid[k])
execvp(.....);
}
}
According to my understanding, i told 1024 total processes will be there including the parent as 2^n -1 = 1023 + 1 parent where n = total forks
But, the interviewer replied that my answer was wrong.
What is wrong with my understanding?
Given this code
pid[k]=fork();
if(!pid[k])
execvp(.....);
and reading the man page of fork which states that
On success, the PID of the child process is returned in the parent,
and 0 is returned in the child.
we know that the child process will perform the exec call (and go on executing a different program), whereas the parent will loop and create another child.
This means that a child will be created for each iteration of the loop, in this case 10 times. So, the answer is 10 children + 1 parent = 11.
Now, if the program that gets started by exec is the same program, the fun will stop only when the computer's memory is exhausted: on every iteration 10 programs will each create 10 children, which each will create 10 children, and so on. A pecularity of fork() is that parent and child get an image of the same variables (which would lead to a predictable number of children, ie some figure related to a power of 2), obviously this isn't true when a program gets exec'd, which means that available memory will be the only limit.

Determining which objects ZwWaitForMultipleObjects is waiting on

Looking at a crash dump in windbg, I can see that all current threads are stalled at
> ~2k
ChildEBP RetAddr
00d2fcc8 7d4e27dc ntdll_7d600000!ZwWaitForMultipleObjects+0x15
or SingleObject variations of the same.
As a handle to the object to wait on is passed to ZwWaitForMultipleObjects, I assumed that I could work out which object it was using a variation of
!do <address>
with the right address -- but I don't know how to construct the right address. I'm assuming I need some offset from the ChildEBP?
Try these steps:
Use the "~2s" command to switch context to thread #2 (this step is arguably redundant but I find it easier to operate in the right thread context)
Use the "kb" command to display the thread's call stack including each function's first three arguments. You will get something like:
ChildEBP RetAddr Args to Child
0dc7fa30 768b0962 00000004 0dc7fa80 00000001 ntdll!ZwWaitForMultipleObjects+0x15
0dc7facc 73c61339 0dc7fa80 0dc7fb14 00000000 KERNELBASE!WaitForMultipleObjectsEx+0x100
Taking the above call stack as an example, you can see that the number of handles passed to ZwWaitForMultipleObjects is 4 (the value of the first argument). The address of the handle array is the second argument. In the above example the address is 0dc7fa80
Use the "dd" command to display the contents of the handle array. In the case of the above call stack, use "dd 0dc7fa80" which will give something like:
0dc7fa80 000001f0 000001f8 0000020c 000001ec
0dc7fa90 73a53c1b 00000000 0d462f70 00000001
0dc7faa0 0cf7afe0 00000003 0dc7fac8 00000004
Assuming this is a 32bit process, the handles are the first four individual DWORDs: "1f0", "1f8", "20c" and "1ec".
You can see the details of each handle using the "!handle" WinDbg extension like so:
!handle 1f0 F
The F flag will display more details about the handle, including its count and name (if it has one associated with it)
If you suspect the handles were passed in from managed code, then you'll need to load SOS or PSSCOR and use the !ClrStack command to display the managed call stack details.

Is there a way in windbg to create a break point that will fire when a certain parameter is passed on the stack?

I'm trying to track down who is making an allocation of a certain size, and I tried using the user mode stack trace db (gflags +ust), but due to FPO I can't see the entire stack. So instead I wanted to set a breakpoint on RtlAllocateHeap when it makes the allocation size I'm looking for. The only problem is I can't seem to find out a way to get this to work.
I initially tried using #esi since it looked like the third parameter was being passed using this register, but it doesn't appear that's always the case. So then I tried #ebp-c to give me the third parameter, but that doesn't appear to always work, so I tried #esp+14 and that didn't work either.
No matter what I do I can't seem to find a way to get this to actually fire when I want it to. It seems like this should work, but I'm guessing it is using leaf function optimizations in certain cases which is preventing me from being able to do this.
Anyone have any ideas on how to get this to work.
Heap stack trace:
0:013> !heap -p -a 0c060710
address 0c060710 found in
_HEAP # 1420000
HEAP_ENTRY Size Prev Flags UserPtr UserSize - state
0c0606f8 09c3 0000 [00] 0c060710 04e00 - (busy)
77abb234 ntdll!RtlAllocateHeap+0x00000274
75ee404b ole32!CRetailMalloc_Alloc+0x00000016
76454557 OLEAUT32!APP_DATA::AllocCachedMem+0x00000060
7645476a OLEAUT32!SysAllocStringByteLen+0x0000003d
764547bf OLEAUT32!ErrStringCopyNoNull+0x00000016
764547e3 OLEAUT32!VariantCopy+0x0000007f
Break points tried:
bp ntdll!RtlAllocateHeap "j #esi == 0x4e00 ''; 'gc'"
bp ntdll!RtlAllocateHeap "j poi(#ebp-c) == 0x4e00 ''; 'gc'"
bp ntdll!RtlAllocateHeap "j poi(#esp+14) == 0x4e00 ''; 'gc'"
I think I have tested this:
Break on allocation size == 1303
bp ntdll!RtlAllocateHeap "j(poi(#esp+c) = 0x1303) 'k';'gc'"
Use poi(#esp+c)
At the first instruction of the function, you do not have EBP. So the structure on the stack for cdecl and stdcall is
<return address>
<First arg>
<second arg>
etc.