Reputation: 3233
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.
Upvotes: 0
Views: 2954
Reputation: 9007
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"
Upvotes: 2
Reputation: 5489
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
Upvotes: 4