WinDbg: Regarding output of dt command - windbg

When I dump the details of a local variable using the dt command in WinDbg i get the following output:
0:000> dt uid_out
Local var # 0x84ebbac Type CString*
0x084ebbfc
+0x000 m_pchData : 0x082f2988 -> 0x31
My query is what does -> 0x31 in the final line specify? Does it specifies the size of the CString?
Thanks in advance!

This is the value of the first element of the array pointed to by a pointer type. Since m_pchData is a pointer to CHAR, the debugger shows you the first CHAR value at address 0x82f2988.

My query is what does -> 0x31 in the final line specify? Does it
specifies the size of the CString?
It's not being that smart, I suspect it's just the first byte of the pointer contents. You can confirm with:
dc 0x082f2988

Related

Strange results when deleting all special characters from a string in Progress / OpenEdge

I have the code snippet below (as suggested in this previous Stack Overflow answer ... Deleting all special characters from a string in progress 4GL) which is attempting to remove all extended characters from a string so that I may transmit it to a customer's system which will not accept any extended characters.
do v-int = 128 to 255:
assign v-string = replace(v-string,chr(v-int),"").
end.
It is working perfectly with one exception (which makes me fear there may be others I have not caught). When it gets to 255, it will replace all 'y's in the string.
If I do the following ...
display chr(255) = chr(121). /* 121 is asc code of y */
I get true as the result.
And therefore, if I do the following ...
display replace("This is really strange",chr(255),"").
I get the following result:
This is reall strange
I have verified that 'y' is the only character affected by running the following:
def var v-string as char init "abcdefghijklmnopqrstuvwxyz".
def var v-int as int.
do v-int = 128 to 255:
assign v-string = replace(v-string,chr(v-int),"").
end.
display v-string.
Which results in the following:
abcdefghijklmnopqrstuvwxz
I know I can fix this by removing 255 from the range but I would like to understand why this is happening.
Is this a character collation set issue or am I missing something simpler?
Thanks for any help!
This is a bug. Here's a Progress Knowledge Base article about it:
http://knowledgebase.progress.com/articles/Article/000046181
The workaround is to specify the codepage in the CHR() statement, like this:
CHR(255, "UTF-8", "1252")
Here it is in your example:
def var v-string as char init "abcdefghijklmnopqrstuvwxyz". def var v-int as int.
do v-int = 128 to 255:
assign v-string = replace(v-string, chr(v-int, "UTF-8", "1252"), "").
end.
display v-string.
You should now see the 'y' in the output.
This seems to be a bug!
The REPLACE() function returns an unexpected result when replacing character CHR(255) (ÿ) in a String.
The REPLACE() function modifies the value of the target character, but additionally it changes any occurrence of characters 'Y' and 'y' present in the String.
This behavior seems to affect only the character ÿ. Other characters are correctly changed by REPLACE().
Using default codepage ISO-8859-1
Link to knowledgebase

searchMemory function in pykd

I'm trying to understand how to use the searchMemory() function in pykd extension for windbg.
The documentation says the following:
Function searchMemory
searchMemory( (long)arg1, (int)arg2, (list)arg3) -> int :
Search in virtual memory
C++ signature :
unsigned __int64 searchMemory(unsigned __int64,unsigned long,class boost::python::list)
searchMemory( (long)arg1, (int)arg2, (str)arg3) -> int :
Search in virtual memory
C++ signature :
unsigned __int64 searchMemory(unsigned __int64,unsigned long,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >)
Does someone know what the arguments are and how should I use this function?
First, note that there are 2 overloads of the same method:
searchMemory( (long)arg1, (int)arg2, (list)arg3) -> int
and
searchMemory( (long)arg1, (int)arg2, (str)arg3) -> int
arg1 is the start address or offset at which to start the search,
arg2 is the length or amount of memory to search and
arg3 is the search term, which can be
a string (std::string) or
a list (of char)
the return value is an offset again, certainly the offset of the first occurrence, so to find the next occurrence, you have to search again
I have interpreted all this from the sources in pymemaccess.cpp [Codeplex] and never used it myself yet.
I'm neither very familiar with C++ nor with Python and even worse for the mapping between the two, but IMHO the std::string is a string of bytes and not Unicode characters, so you can put arbitraty bytes in there. It should also be suitable for ASCII search. But you might have to fiddle a bit for UTF-16 / UCS text. The same probably applies for the list of char, because it's not declared as wchar_t.

Analyze dump file using WinDbg with SOS: How do I get the urls of all currently executing requests?

I have a dump file from a w3c process that I need to analyze.
According to a "!DumpHeap -type HttpRequest", there are currently some three thousand active connections to the server.
The question is if it is possible to get the requested URLs of these connections? I would really like to avoid doing a !do for each object to find the reference of the "url" property..
.foreach (object {!DumpHeap -type System.Web.HttpRequest -short}) { !do ${object} }
This will dump every HttpRequest. The URL is a bit deeper down. First you have to find the offset of the _url property:
MT Field Offset Type VT Attr Value Name
000007feedc1cc70 4000d7d 90 System.Uri 0 instance 00000000025f2020 _url
In this case (64 bit) it's at offset 0x90. To dump all the Uri objects, replace the !do ${object} by !do poi(${object}+90). But still this is not the URL, so let's see:
MT Field Offset Type VT Attr Value Name
000007feeeaa68f0 400161c 8 System.String 0 instance 00000000025f1e18 m_String
000007feeeaa68f0 400161d 10 System.String 0 instance 0000000000000000 m_originalUnicodeString
At offset 0x8, the URI has a string and at 0x10 another string. Again we add the offset, so exchange !do poi(${object}+90) by !do poi(poi(${object}+90)+8) (or +10). This will print the .NET string object with all fields. If you want the pure string, do it once again:
MT Field Offset Type VT Attr Value Name
000007feeeaab318 4000104 c System.Char 1 instance 68 m_firstChar
This time we're not using !do any more, because we're on raw bits and bytes and dump a unicode string with du poi(poi(${object}+90)+8)+c. The total command for all HttpRequests is then:
.foreach (object {!DumpHeap -type System.Web.HttpRequest -short}) { du poi(poi(${object}+90)+8)+c }
Some variant of the .foreach command, e.g.
.foreach (object {!sos.DumpHeap -type System.String -short}) { !sos.DumpObj object }

How to return next string without >> with stringstream?

Instead of:
stringstream szBuffer;
szBuffer>>string;
myFunc(string);
How do I do like:
muFunc(szBuffer.NextString());
I dont want to create a temp var just for passing it to a function.
If you want to read the whole string in:
// .str() returns a string with the contents of szBuffer
muFunc(szBuffer.str());
// Once you've taken the string out, clear it
szBuffer.str("");
If you want to extract the next line (up to the next \n character), use istream::getline:
// There are better ways to do this, but for the purposes of this
// demonstration we'll assume the lines aren't longer than 255 bytes
char buf[ 256 ];
szBuffer.getline(buf, sizeof(buf));
muFunc(buf);
getline() can also take in a delimiter as a second parameter (\n by default), so you can read it word by word.

How to Iterate through Memory Dump in Windbg?

I have an array of Relative Virtual Addresses (RVAs) located at a particular memory address. I can dump it in windbg and see the list of RVAs as show below:
dd 77f10000+00002650 and
output is:
77f12650 000034a6 000034af 000034b9 000034ce
....
Here, 77f10000 is the base address of the DLL and 00002650 is the RVA of the array which I have displayed.
Now, each of these RVA's in the memory dump can be added to the base address of the DLL and the corrresponding string at the location can be viewed.
For instance, if I take the first entry in the array which is: 000034a6
By adding this RVA to the base address of DLL, 77f10000 and displaying it as follows:
da 77f10000+000034a6 and
output is: 77f134a6 "AbortDoc"
now, this way, I can view the next string for the next corresponding RVA in the array by doing the following:
da 77f10000+000034af and
output is: 77f134af "AbortPath"
Similarly I want to iterate over the remaining entries in the array and display the corresponding strings.
I want to do this using a one liner script in windbg. I want to learn how to do this however I could not find enough documentation or examples around on the net which would help me craft something similar.
I think the, .foreach command can be used to do this:
Example: .foreach(myVariable {dd 77f10000+00002650}){!do }
myVariable is going to store the output of the windbg command. However, I need to pick one element at a time from the line and iterate.
Any help would be appreciated.
Thanks.
It's unfortunately harder than it should be because the dd command displays not only the result but the address of the result, so .foreach is going to iterate over both. While I couldn't do it in one line, I did it in a script file that only looks long because of the comments:
$$ Set up the base of the RVA array as a pointer to an integer.
r? #$t0 = ((int *)(0x8068f764))
$$ To break down the command:
$$ r? - Allows you to assign a pseudo register and give it a type
$$ #$t0 - Pseudo register for use in scripting
$$ ((int *)(address) - Assign the type int * to the result
$$ Loop over the entries in the array, 100 is arbitrary and should be replaced
.for (r #$t1 = 0; #$t1 < 100; r #$t1 = #$t1 + 1)
{
$$ Display the ASCII string at the given offset. This is similar to:
$$
$$ printf("%s\n", baseAddr+(offsetArray[i])
$$
$$ ##c++() is required so that #$t0 is treated as an int *
da nt+(##c++(#$t0[#$t1]));
}
Save to a TXT file and run with the following command:
0: kd> $$><c:\dumps\dumprvas.txt
80691a4b "CcCanIWrite"
80691a57 "CcCopyRead"
80691a62 "CcCopyWrite"
80691a6e "CcDeferWrite"
80691a7b "CcFastCopyRead"
80691a8a "CcFastCopyWrite"
...
If I were doing this for real I'd clean that up even more and make the base address and entry count parameters to the script, which would make it more useful. I left it out here though for clarity (well, as much clarity as can be expected with these scripts :)).
-scott
very late answer but here is a oneliner as requested :)
0:000> .foreach /ps 1 /pS 1 (place { dd /c 1 gdi32+2650 l?5 }) {da gdi32 + place }
test output
0:000> .foreach /ps 1 /pS 1 (place { dd /c 1 gdi32+2650 l?5 }) {da gdi32 + place }
77f134a6 "AbortDoc"
77f134af "AbortPath"
77f134b9 "AddFontMemResourceEx"
77f134ce "AddFontResourceA"
77f134df "AddFontResourceExA"