How to reference 32bit integer data in a 64 bit dump - windbg

If I have a System.Int32 at a known memory address of a 64-bit .Net process dump, how can I reference its data in a condition or expression in windbg? For example:
? poi(000000ba2e4de938) == 0n27 is displaying as 0 instead of 1, even though I know that the value at that address is 27 (dt int 000000ba2e4de938 displays 0n27). It is doing so, because it picks up 32 junk bits after the value I am attempting to access, since poi grabs pointer-sized data.
Is there a way to grab data of a certain size to use within expressions? I have so far only found ways to dump the data, but not use it within expressions or conditions.

Short answer: use dwo(...) for 32 bits, qwo(...) for 64 bits and poi(...) for architecture dependent size.
Long answer:
Let's look at an Int32 with SOS first:
0:014> .symfix
0:014> .reload
0:014> .loadby sos clr
0:006> !name2ee *!System.Int32
Module: 000007feecab1000
Assembly: mscorlib.dll
Token: 00000000020000f0
MethodTable: 000007feed1603d0
EEClass: 000007feecb71810
Name: System.Int32
[...]
0:006> !dumpheap -mt 000007feed1603d0
Address MT Size
00000000028376d8 000007feed1603d0 24
0:006> !do 00000000028376d8
Name: System.Int32
MethodTable: 000007feed1603d0
EEClass: 000007feecb71810
Size: 24(0x18) bytes
File: C:\Windows\Microsoft.Net\assembly\GAC_64\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll
Fields:
MT Field Offset Type VT Attr Value Name
000007feed1603d0 400055f 8 System.Int32 1 instance 8868 m_value
From that output, you can see that the value (m_value) of the Int32 is at the address of the object + an offset of 8.
The length of Int32 is 32 bit, so we need the dd (dump DWORD) to look at the memory:
0:006> dd 00000000028376d8+8 L1
00000000`028376e0 000022a4
Convert that into decimal and it'll be what has been displayed by SOS before:
0:006> ? 22a4
Evaluate expression: 8868 = 00000000`000022a4
To use it in a condition, use dwo (DWORD size) instead of poi (pointer size, which is qwo on 64 bits):
0:006> ? dwo(00000000028376d8+8)
Evaluate expression: 8868 = 00000000`000022a4

Related

how to set max-functions in pcie device tree? (about the syntax "max-functions = /bits/ 8 <8>;")

In linux-6.15.68, in Documentation/devicetree/bindings/pci/rockchip-pcie-ep.txt, I see these explanations. (please see the marked line.)
Optional Property:
- num-lanes: number of lanes to use
- max-functions: Maximum number of functions that can be configured (default 1).
pcie0-ep: pcie#f8000000 {
compatible = "rockchip,rk3399-pcie-ep";
#address-cells = <3>;
#size-cells = <2>;
rockchip,max-outbound-regions = <16>;
clocks = <&cru ACLK_PCIE>, <&cru ACLK_PERF_PCIE>,
<&cru PCLK_PCIE>, <&cru SCLK_PCIE_PM>;
clock-names = "aclk", "aclk-perf",
"hclk", "pm";
max-functions = /bits/ 8 <8>; // <---- see this line
num-lanes = <4>;
reg = <0x0 0xfd000000 0x0 0x1000000>, <0x0 0x80000000 0x0 0x20000>;
<skip>
In the example dts, what does "max-functions = /bins/ 8 <8>;" mean?
I found in Documentation/devicetree/bindings/pci/snps,dw-pcie-ep.yaml, it says
max-functions:
$ref: /schemas/types.yaml#/definitions/uint32
description: maximum number of functions that can be configured
But I don't know how to read the $ref document.
ADD
I found this.
The storage size of an element can be changed using the /bits/ prefix. The /bits/ prefix allows for the creation of 8, 16, 32, and
64-bit elements. The resulting array will not be padded to a
multiple of the default 32-bit element size.
e.g. interrupts = /bits/ 8 <17 0xc>; e.g. clock-frequency = /bits/
64 <0x0000000100000000>;
Does this mean 17 and 0xc are both 8-bit variables and when it is compiled to dtb, it keep the 8-bit format? The linux code will analyze the dtb file, then does the dtb contains the format information too?
The Device Tree Compiler v1.4.0 onwards supports some extra syntaxes for specifying property values that are not present in The Devicetree Specification up to at least version v0.4-rc1. These extra property value syntaxes are documented in the Device Tree Compiler's Device Tree Source Format and include:
A number in an array between angle brackets can be specified as a character literal such as 'a', '\r' or '\xFF'.
The size of elements in an array between angle brackets can be set using the prefix /bits/ and a bit-width of 8, 16, 32, or 64, defaulting to 32-bit integers.
The binary Flattened Devicetree (DTB) Format contains no explicit information on the type of a property value. A property value is just a string of bytes. Numbers (and character literals) between angle brackets in the source are converted to bytes in big-endian byte order in accordance with the element size in bits divided by 8. For example:
<0x11 'a'> is encoded in the same way as the bytestring [00 00 00 11 00 00 00 61].
/bits/ 8 <17 0xc> is encoded in the same way as the bytestring [11 0c].
It is up to the reader of the property value to "know" what type it is expecting. For example, the Rockchip AXI PCIe endpoint controller driver in the Linux kernel ("drivers/pci/controller/pcie-rockchip-ep.c") "knows" that the "max-functions" property should have been specified as a single byte and attempts to read it using the statement err = of_property_read_u8(dev->of_node, "max-functions", &ep->epc->max_functions);. (It is probably encoded as a single byte property for convenience so that it can be copied directly into the u8 max_functions member of a struct pci_epc.)

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.

Convert text to binary and store in a single array in matlab

I need to convert the given text (not in file format) into binary values and store in a single array that is to be given as input to other function in Matlab .
Example:
Hi how are you ?
It is to be converted into binary and stored in an array.I have used dec2bin() function but i did not suceed in getting the output required.
Sounds a bit like a trick question. In MATLAB, a character array (string) is just a different representation of 16-bit unsigned character codes.
>> str = 'Hi, how are you?'
str =
Hi, how are you?
>> whos str
Name Size Bytes Class Attributes
str 1x16 32 char
Note that the 16 characters occupy 32 bytes, or 2 bytes (16-bits) per character. From the documentation for char:
Valid codes range from 0 to 65535, where codes 0 through 127 correspond to 7-bit ASCII characters. The characters that MATLABĀ® can process (other than 7-bit ASCII characters) depend upon your current locale setting. To convert characters into a numeric array,use the double function.
Now, you could use double as it recommends to get the character codes into double arrays, but a minimal representation would simply involve uint16:
int16bStr = uint16(str)
To split this into bytes, typecast into 8-bit integers:
typecast(int16bStr,'uint8')
which yields 32 uint8 values (bytes), which are suitable for conversion to binary representation with dec2bin, if you want to see the binary (but these arrays are already binary data).
If you don't expect anything other than ASCII characters, just throw out the extra bits from the start:
>> int8bStr =
72 105 44 32 104 111 119 32 97 114 101 32 121 111 117 63
>> binStr = reshape(dec2bin(binStr8b.'),1,[])
ans =
110011101110111001111111111111110000001001001011111011000000 <...snip...>

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 }

in windbg how to save byte array to the file

before i had see this question and answer: Use WinDbg to Write Contents of Managed Byte[] to File,but i have a question that the mention answer that write all bytes to the file( Method table pointer,array length and the array content),i want just write a array content to the file.
for example,i created a byte array with 8192 length.
var bytes=new Byte[8192]
and use windbg and crash this.
0:034> !do 0x0143fd1c
Name: System.Byte[]
MethodTable: 5ce54944
EEClass: 5cb8af1c
Size: 8204(0x200c) bytes
Array: Rank 1, Number of elements 8192, Type Byte
Element Type:System.Byte
Content: .0.................:.i......$...,x"!.a_.h#......66..vx.4...P.R?...M
Fields:
None
0:034> dd 0x0143fd1c
0143fd1c 5ce54944 00002000 0a0d300a 16460a0d
0143fd2c 957bd993 1f92335c 79a2d058 72455ef6
0143fd3c cc16c7b1 05b18e14 5b1df595 0fb5dbd8
0143fd4c 629a16c6 0edb5c9a 6ede4110 5d5da54e
0143fd5c 4638143a efcad6db 060935f1 a9a48285
0143fd6c e414cff0 8aeaae92 f169b93a f80bd6de
0143fd7c 9a9824d1 22782ccd 5f610c21 0f2368b4
0143fd8c ae09d410 083636c3 0b787616 101ab234
0:034> !da 0143fd1c
Name: System.Byte[]
MethodTable: 5ce54944
EEClass: 5cb8af1c
Size: 8204(0x200c) bytes
Array: Rank 1, Number of elements 8192, Type Byte
Element Methodtable: 5ce525ec
[0] 0143fd24
[1] 0143fd25
.......
so,how to location at start offset and output length in the .writemem command?thanks.
!da gives you the answer.
[0] 0143fd24<-- Address of first byte here.
Take the address of the first byte and pass it to .writemem along with a file name.
.writemem C:\somefile 143fd24 L0n8192
This command says write to C:\somefile, data starting at 143fd24, continuing for decimal 8192 bytes.