Play back to the moment of creation of some managed object in WinDbg TTD - clr

Using WinDbg with TTD enabled, how to play back to the moment of creation of some managed object?
Lets say I do have its address obtained using !clrstack -a or !dso

There are several ways of doing this. If you have the address of the object and want to go back to its creation you can use a ba (break on access). When an object is created the Method Table address is written into the first word (4 bytes for 32-bit, 8 bytes for 64-bit). So adding a breakpoint per write access and going backwards will stop at the object creation. Another way is to add breakpoints pointing to all constructors of the object and also going backwards. Also notice that all of this can also be done by a 'dx' command filtering by breakpoint address or constructor call.
Imagine you have this output:
0:016> !dso
OS Thread Id: 0x2f54 (16)
RSP/REG Object Name
000000A2CD5FC770 000001e9849cd4b8 ConceptNetConsole1.SampleClass1
(...)
0:016> !DumpObj /d 000001e9849cd4b8
Name: ConceptNetConsole1.SampleClass1
MethodTable: 00007ffb85545ef8 <<< This is the method table
EEClass: 00007ffb85542d68
Size: 136(0x88) bytes
File: C:\Projects\ConceptNetConsole1\ConceptNetConsole1\bin\x64\Release\ConceptNetConsole1.exe
Fields:
MT Field Offset Type VT Attr Value Name
00007ffbe38e70b0 40005a8 8 System.Object 0 instance 000001e9849cd718 __identity
(...)
Approach 1:
And you want to stop when this object is created you can use (for 32-bit use w4):
ba w8 000001e9849cd4b8
g-
Using 'dx' (notice that the address must be in C++ format, starting wit '0x'):
dx -g #$cursession.TTD.Memory(0x00001e9849cd4b8,0x00001e9849cd4b8+8,"w")
Again, for 32-bit use address+4 on the second parameter. The option -g will show in a grid format.
Approach 2:
Get the address(es) of the constructors by listing the methods table of the class:
0:016> !dumpmt -md 00007ffb85545ef8
EEClass: 00007ffb85542d68
Module: 00007ffb85545408
Name: ConceptNetConsole1.SampleClass1
mdToken: 0000000002000005
File: C:\Projects\ConceptNetConsole1\ConceptNetConsole1\bin\x64\Release\ConceptNetConsole1.exe
BaseSize: 0x88
ComponentSize: 0x0
Slots in VTable: 23
Number of IFaces in IFaceMap: 0
--------------------------------------
MethodDesc Table
Entry MethodDesc JIT Name
00007ffbe36fb1f0 00007ffbe3257538 PreJIT System.Object.ToString()
00007ffbe36ffd90 00007ffbe3257540 PreJIT System.Object.Equals(System.Object)
00007ffbe3721dc0 00007ffbe3257568 PreJIT System.Object.GetHashCode()
00007ffbe36fce50 00007ffbe3257580 PreJIT System.Object.Finalize()
00007ffbe37d8f40 00007ffbe333cfd0 PreJIT System.MarshalByRefObject.GetLifetimeService()
00007ffbe36f8b10 00007ffbe333cfd8 PreJIT System.MarshalByRefObject.InitializeLifetimeService()
00007ffbe37cbd80 00007ffbe333cfe0 PreJIT System.MarshalByRefObject.CreateObjRef(System.Type)
00007ffb85560090 00007ffb85545d58 JIT ConceptNetConsole1.SampleClass1..ctor() <<< This is the constructor
(...)
You may simply set the breakpoint at the 'Entry' address (or use !sos.bpmd) and go backwards:
bp 00007ffb85560090
g-
Or use 'dx' to show all occasions where the code was called (note that the code was again adjusted to look like C++ '0x' and also that is in quotes):
dx -g #$cursession.TTD.Calls("0x00007ffb85560090")
Hope it works for you.

Related

Cobol Filestatus 98

I am dynamically creating a PS file (based on timestamp from input file) on the Cobol program and using it as output file to write transaction details, but if the input file s received twice, job is failing with duplicate dataset. So I thought of rewrite the file if the file is already allocated. To do this i have tried all these options I-O/Extend/Output to open the output file but it is failing with Filestatus 98
Any idea how can to do this?
DISPLAY '5000-B-->'
PERFORM 5000-ALLOCATE-ACK-FILE [ Allocate File Dynamically]
DISPLAY '5000-A-->'
DISPLAY 'I-O--B-->'
OPEN OUTPUT OUT-ACK-FILE
DISPLAY 'WS-OUTACK-STATUS-->' WS-OUTACK-STATUS
DISPLAY 'I-O--A-->'
Error:
ALLOCATE OK 00
5000-A-->
I-O--B-->
IGZ0255W Dynamic allocation failed for ddname OUTACK while processing file OUT-A
return code from the dynamic allocation was X'4', error code X'FFFFFFFF
information code X'0'.
WS-OUTACK-STATUS-->98
I-O--A-->
You don't show details of how the allocation is done, or how you check for existence of the data set.
Anyway, on z/OS the DISP parameter of the allocation of a PS data set determines whether the data written replaces the current content (if any), or whether it is appended to the current content (if any).
DISP=NEW and DISP=OLD replace
DISP=MOD appends.
The OPEN parameters don't vary.

memory trace of all variables in program with DBI tool

I am using intel pin as my primary DBI tool.
I am interested to know how can I trace all variables allocated in a program .
suppose, we have the following snippet in C:
int *ptr_one, *ptr_two, g;
ptr_one = (int *)malloc(sizeof(int));
ptr_two = (int *)malloc(sizeof(int));
*ptr_one = 25;
*ptr_two = 24;
g = 130;
free(ptr_two);
g = 210;
*ptr_two = 50;
I want to know how can I trace specific variables / memory references in my program . for example on the above code, I like to trace the variable "g" in my program with Intel Pin, how it can be done?
for dynamically allocated variables, I'm monitoring malloc/free calls & follow their addresses, but for static ones I do not have any idea .
Another matter is, for dynamically allocated variables, I like to trace them across the whole program, suppose in the above code, I want to monitor (ptr_two) variable changes and modification during my program from start to finish .
If anyone have some idea about that, it can be nice to share it here, sample codes appreciated in Intel Pin .
thank you all .
Simply stated, you can't associate a name from your source code (be it variable or function name) with a memory location on the compiled binary: this information is (probably) lost on the final binary.
This is not true in two cases:
1) If your binary is exporting functions: in this case other binaries must have a means to call the function by name (minus some subtleties), in which case the information must be available somewhere; for example on Windows, binaries that export functions, variables or classes have an export table.
2) You have symbolic information: in your example, either for the global variable or other local variable, you have to use the symbolic information provided by the compiler.
On Linux you will need an external tool / library / program (e.g. libelf.so or libdwarf.so) to parse the symbolic information from the symbol tables (usually dynsym / symtab) if the binary is not stripped.
On windows you have to rely on the program database (*.pdb files); the format is mostly undocumented (although MS is trying to document it) and you have to use either the DbgHelp API or the DIA SDK.
As stated by the PIN user guide (emphasis is mine):
Pin provides access to function names using the symbol object (SYM).
Symbol objects only provide information about the function symbols in
the application. Information about other types of symbols (e.g. data
symbols), must be obtained independently by the tool.
If you have symbolic information you can then associate a variable name - obtained from an external tool - with an address (relative to the module base for global vars or a stack location for local ones). At runtime it is then just a matter of converting the relative address to a virtual one.

Windows driver dev: Can ntoskrnl code get paged out?

I'm trying my driver with Driver Verifier turned on in Windows 7 x64, and get IRQL_NOT_LESS_OR_EQUAL(0A) bugcheck. From analyze -v info, it seems that the memory page of RtlAnsiCharToUnicodeChar function gets paged out, so calling that function causes bugcheck 0A . RtlAnsiCharToUnicodeChar is an ntoskrnl.exe exported function. Can it really be paged out? If so, how can I prevent it?
On spot debug info screen shot below:
yes. of course - very many ntoskrnl routines in PAGE* section.
RtlAnsiCharToUnicodeChar also paged - read in documentation:
IRQL <= APC_LEVEL
also read about DbgPrintEx routine
DbgPrint and DbgPrintEx can be called at IRQL<=DIRQL. However, Unicode
format codes (%wc and %ws) can be used only at IRQL = PASSIVE_LEVEL.
and
However, the Unicode format codes (%C, %S, %lc, %ls, %wc, %ws, and
%wZ) can only be used with IRQL = PASSIVE_LEVEL.
so if you not use Unicode format you can use DbgPrint or KdPrint(this is macro) at any IRQL but if you use Unicode format - only on PASSIVE_LEVEL or APC_LEVEL (about APC_LEVEL i say by self)
You can try to use the MmLockPagableCodeSection on that specific routine to prevent it being paged out, however it's probably not advisable (and you don't know what dependencies it has, if they're located in pagable sections as well). In any case, make sure you read the documentation thoroughly.
A better approach is to run at Passive/APC level in the first place before invoking the printing function - e.g., by scheduling work item (you can also force lowering the IRQL with KeLowerIrql function but it's not advisable by MSFT).

Navigate from stackframe to stackframe in the Managed stack inside CDB/WinDbg

I have been given a dozen of dump files. Using windbg/sosex command !dumpstack -EE, a lot of them show these lines by the end :
0aa6ce7c 028ea126 (MethodDesc 02756288 +0x16 TheCompany.Toolbox.Log.Logger.Info(System.String))
0aa6cecc 028ea126 (MethodDesc 02756288 +0x16 TheCompany.Toolbox.Log.Logger.Info(System.String))
0aa6cf54 028ea126 (MethodDesc 02756288 +0x16 TheCompany.Toolbox.Log.Logger.Info(System.String))
0aa6d080 6f42bc51 (MethodDesc 6f1da670 +0x81 System.TimeSpan.TimeToTicks(Int32, Int32, Int32))
0aa6d0a8 6f42c0a0 (MethodDesc 6f1daf1c +0x40 System.DateTime.TimeToTicks(Int32, Int32, Int32))
0aa6d0d0 6f42cb8f (MethodDesc 6f1da8ec +0x7f System.DateTime.Add(Double, Int32))
Unfortunately, trying to get the local variable with !clrstack -a does not give me sensible results:
0:045> !clrstack -a
OS Thread Id: 0xf50 (45)
Child SP IP Call Site
0aa6ed78 76df7094 [GCFrame: 0aa6ed78]
0aa6ef5c 76df7094 [DebuggerU2MCatchHandlerFrame: 0aa6ef5c]
Is there a way to move to another frame than the last one ? ( so as to get the locals in this frame).
In native mode, I can do :
.frame #$.frame +1
then I can have the locals in that previous frame with
dv
I wonder how to do the same with the managed stack, so as I can do !clrstack -a inside previous frames. I also would like to know the function parameters value/reference in this stackframe.
Are there commands to perform such actions ?
Steve Johnson's SOSEX has the !mframe command.
Although you have tagged the question sosex, you have not used any SOSEX command, only SOS commands, which could be a reason why you did not find the command.
You get the frame numbers from !mk. If you have DML enabled, the frame numbers can be clicked and a !mframe command is automatically done. After that, you can do !mdv to display arguments and locals.
Alternatively, !mdv <frame> also takes a frame number directly.
However, I'm not sure if this always helps. SOSEX can't do magic and needs to rely on the information given by the .NET framework. If that's broken for some reason, you could be unlucky.

GDB 'Addresses'. What are they?

This should be a very simple,very quick qustion. These are the first 3 lines of a program in C I wrote:
Dump of assembler code for function main:
0x0804844d <+0>: push ebp
0x0804844e <+1>: mov ebp,esp
0x08048450 <+3>: and esp,0xfffffff0
... ... ... ... ... ... ...
What is 0x0804844d and 0x0804844e and 0x08048450? It is not affected by ASLR. Is it still a memory address, or a relative point to the file?
If you look at the Intel Developer Manual instruction-set reference you can see that 0x0804846d <+32>: eb 15 jmp 0x8048484 encodes a relative address. i.e. it's the jmp rel8 short encoding. This works even in position-independent code, i.e. code which can run when mapped / loaded at any address.
ASLR means that the address of the stack (and optionally code+data) in the executable can change every time you load the file into memory. Obviously, once the program is loaded, the addresses won't change anymore, until it is loaded again. So if you know the address at runtime, you can target it, but you can't write an exploit assuming a fixed address.
GDB is showing you addresses of code in the virtual-memory space of your process, after any ASLR. (BTW, GDB disables ASLR by default: set disable-randomization on|off to toggle.)
For executables, it's common that only the stack pointer is ASLRed, while the code is position-dependent and loaded at a fixed address, so code and static data addresses are link-time constants, so code like push OFFSET .LC0 / call puts can work, hard-coding the address of the string constant into a push imm32.
Libraries usually need to be position-independent anyway, so ASLR can load them at a randomized address.
But ASLR for executables is possible and becoming more common, either by making position-independent executables (Linux), or by having the OS fix-up every hard-coded address when it loads the executable at a different address than it was compiled for (Windows).
Addresses only have a 1:1 relation to the position within the file only in a relative sense within the same segment. i.e. the next byte of code is the next byte of the file. The headers of the executable describe which regions of the file are what (and where they should be mapped by the OS's program loader).
The meaning of the addresses shown differs in three cases:
For executable files
For DLLs (Windows) or shared objects (.so, Linux and Un*x-like)
For object files
For executables:
Executable files typically cannot be loaded to any address in memory. In Windows there is the possibility to add a "relocation table" to an executable file (required for very old Windows versions); if this is not present (typically the case when using GCC) then it is not possible to load the file to another memory location. In Linux it is never possible to load the executable to another location.
You may try something like this:
static int a;
printf("%X\n", &a);
When you execute the program 100 times you see that the address of a is always the same so no ASLR is done for the executable file itself.
The addresses dumped by objdump are absolute addresses.
For DLLs / .so files:
The addresses are relative to the base address of the DLL (under Linux) or they are absolute addresses (under Windows) that will change when the DLL is loaded into another memory area.
For object files:
When dumping an object file the addresses are relative to the currently displayed section. If there are multiple ".text" sections in a file the addresses will start at 0 for each section.

Resources