so i need to make sure i return the proper object instead of whining
that everything is text and there is no sed awk grep in windbg ok
that makes sense thanks @Bill Messmer
[quote] out of curiosity where you pull siginfo from publics [quote]
no not from public pdbâs I have other sed awk grep ctags combo to get
func sig from headers
i have around 50000 signatures for example i have 8 signatures for
ZwCreateP as below
:\>wc -l fnproto.txt
49547 fnproto.txt
:\>grep ^ZwCreateP fnproto.txt | wc -l
8
:\>grep ^ZwCreateP fnproto.txt | awk â{print $1 , $2 ,$3 ,$4 , $5}â
ZwCreatePagingFile ( In PUNICODE_STRING PageFileName,
ZwCreatePartition ( In_opt HANDLE ParentPartitionHandle,
ZwCreatePort ( Out PHANDLE PortHandle,
ZwCreatePrivateNamespace ( Out PHANDLE NamespaceHandle,
ZwCreateProcess ( Out PHANDLE ProcessHandle,
ZwCreateProcessEx ( Out PHANDLE ProcessHandle,
ZwCreateProfile ( Out PHANDLE ProfileHandle,
ZwCreateProfileEx ( Out PHANDLE ProfileHandle,
:\>
I getline() compare() ,strstr , strchr , strtok split the tokens ,
sprintf_s() m_Control->execute a precooked (.printf " " ," ") which
ouputs the result of .printf to windbg console
sprintf_s(buffer,0x200,â.printf /D "[@$csp l?%x;\">%s + %02x] [ %17s(Num Args = %02d) Returns
to ] = %s%%p%s\n", poi( @$csp
)â,numparams+1,âCSPâ,0,Buffer,numparams,âpoi(@$csp);u poi(@$csp);\">â,ââ);
m_Control->Execute(DEBUG_OUTCTL_ALL_CLIENTS,buffer,DEBUG_EXECUTE_DEFAULT);
there are apparently many limitations and hacks in the code-flow
.printf has some limitations on the input string it appears so if the
input string is x chars it will print if the input char is x+1 it will
fail mysterioulsy
saying syntax // cant evaluate // extra char // some other
undecipherable error // etc etc
i can also add function signatures dynamically when i encounter or
reverse some thing like
the second function below doesnât seem to have any prototype declared
in any headers publicly available
:\>grep -i -r -h --include=*.h RtlpcTo * -A 1
RtlPcToFileHeader(
In PVOID PcValue,
RtlPcToFileHeader(
In PVOID PcValue,
:\>grep -i -r -h --include=*.h RtlpFind * -A 1
:\>
but the pdb does have a function entry for this
0:000> .fnent ntdll!RtlpFindUnicodeStringInSection
Debugger function entry 0295b6b8 for:
(770ed270) ntdll!RtlpFindUnicodeStringInSection | (770ed370)
ntdll!RtlFindNextActivationContextSection
Exact matches:
ntdll!RtlpFindUnicodeStringInSection ()
OffStart: 0005d270
ProcSize: 0x306
Prologue: 0xa
Params: 0n8 (0x20 bytes)
Locals: 0n11 (0x2c bytes)
Non-FPO
0:000> x ntdll!RtlpFindUnicodeStringInSection
770ed270 ntdll!RtlpFindUnicodeStringInSection ()
so i can add a dummy function with 8 args which i can rename at
leisure but i wont be have to be blind when i see it again
int
__stdcall
RtlpFindUnicodeStringInSection (
DWORD RenameMe[0n01],
DWORD RenameMe[0n02],
DWORD RenameMe[0n03],
DWORD RenameMe[0n04],
DWORD RenameMe[0n05],
DWORD RenameMe[0n06],
DWORD RenameMe[0n07],
DWORD RenameMe[0n08] );
if (Entries != 0 )
{
m_Symbols3->GetSymbolEntryString (
&Ids,0,Buffer,sizeof(Buffer),&StringSize);
}
if ( printfninfo(Buffer) == false)
{
if(Entries != 0)
{
char buff[0x100];
ULONG recbytes;
unsigned long argnum;
m_Control->OutputPrompt(DEBUG_OUTCTL_ALL_CLIENTS,âtype
"yes""Number" like "yes 4" \nâ);
m_Control->Input(buff,0x90,&recbytes);
if ( ( strncmp(buff,âyesâ, 3) == 0 ) && (
(strchr(buff,â â) - buff ) == 3 ) )
{
argnum = strtoul( (strchr(buff,â â)+SKIP_TAB),0,16 );
if ( ( argnum != 0 ) && ( argnum != ULONG_MAX ) )
{
addfninfo(Buffer , argnum);
}
else
{
dprintf(âinvalid response addfninfo request\nâ);
}
}
else
{
dprintf(âinvalid response @ addfninfo request\nâ);
}
}
}
where addfninfo does this
if you want to see the spaghetti or download a tarball of the half
baked biscuits drop a hint offline
[quote 3] there are more than one occurance
yes i changed both ( the .shell - cat blah.js shows i changed both in
the post above )
and it didnt seem to work well ill test it when you signal you have
confirmed it works in win 7
ok so the intput ot getmoduleSymbol needs to be a global with type and
location ie i need a private symbol info
that is i can cast some thing to ULONG or SOME_ARCANE_TYPE only if i
have it in pdb as ULONG
0:000> x /v /t /f /d /z ole32!CGIPTable*
pub global 76608688 0 ole32!CGIPTable::vftable'<br>= <no type information><br>prv global 767061f0 4 unsigned long<br>ole32!CGIPTable::_dwCurrSeqNo = 0x100<br>prv global 76600448 4 <function> *<br>ole32!CGIPTable::_palloc$initializer$ = 0x765ff96f<br>prv global 76708994 4 int ole32!CGIPTable::_fInNAUninit = 0n0<br>prv global 76708990 4 int ole32!CGIPTable::_fInRevokeAll = 0n0<br>prv global 76707368 30 class COleStaticMutexSem<br>ole32!CGIPTable::_mxs = class COleStaticMutexSem<br>prv global 76706c94 34 class CPageAllocator<br>ole32!CGIPTable::_palloc = class CPageAllocator<br>prv global 76706a08 44 struct tagGIPEntry<br>ole32!CGIPTable::_InUseHead = struct tagGIPEntry<br><br>first two will work but not the third because it has no type<br><br>0:000> dx @$scriptContents.host.getModuleSymbol("ole32.dll",<br>"CGIPTable::_dwCurrSeqNo", "unsigned long")<br>@$scriptContents.host.getModuleSymbol("ole32.dll",<br>"CGIPTable::_dwCurrSeqNo", "unsigned long") : 0x100<br><br>0:000> dx @$scriptContents.host.getModuleSymbol("ole32.dll",<br>"CGIPTable::_dwCurrSeqNo", "_LARGE_INTEGER").u<br>@$scriptContents.host.getModuleSymbol("ole32.dll",<br>"CGIPTable::_dwCurrSeqNo", "_LARGE_INTEGER").u [Type:<br>_LARGE_INTEGER::<unnamed-type-u>]<br> [+0x000] LowPart : 0x100 [Type: unsigned long]<br> [+0x004] HighPart : 0 [Type: long]<br><br>0:000> dx @$scriptContents.host.getModuleSymbol("ole32.dll",<br>"CGIPTable::
vftableâ", â_LARGE_INTEGERâ).u
Error: Invalid argument to method âgetModuleSymbolâ
0:000> dx @$scriptContents.host.getModuleSymbol(âole32.dllâ,
"CGIPTable::vftable'", "int")<br>Error: Invalid argument to method 'getModuleSymbol'<br>0:000> dx @$scriptContents.host.getModuleSymbol("ole32.dll",<br>"CGIPTable::_dwCurrSeqNo", "int")<br>@$scriptContents.host.getModuleSymbol("ole32.dll",<br>"CGIPTable::_dwCurrSeqNo", "int") : 0x100<br><br>the last example of extensing always seem to be elusive here in my<br>tests earlier as well as now<br><br>:\>echo file contents of js\gsa.js & cat js\gsa.js<br><br>file contents of js\gsa.js<br>function gsa(sym)<br>{<br> return host.evaluateExpression("(unsigned__int64)(&" + sym + ")");<br>}<br><br>:\>echo file contents of js\rungsa.txt & cat js\rungsa.txt<br><br>file contents of js\rungsa.txt<br>.load jsprovider<br>.scriptload js\gsa.js<br>.echo "Hi my test of gsa starts here"<br>dx @$scriptContents.gsa("WinMain")<br>dx @$scriptContents.gsa(\"WinMain\")<br>dx @$scriptContents.gsa( @$ip )<br>dx @$scriptContents.gsa( 0x7ffd0000 )<br>dx @$scriptContents.gsa( "0x7ffd0000" )<br>dx @$scriptContents.host.evaluateExpression( "(long) 0x80000001" ),x<br>q<br><br>:\>cdb -c "$$>a< js\rungsa.txt" calc<br><br>Microsoft (R) Windows Debugger Version 10.0.14951.1001 X86<br><br>0:000> cdb: Reading initial command '$$>a< js\rungsa.txt'<br>JavaScript script successfully loaded from<br>'E:\windjs\wdbg\Debuggers\x86\js\gsa.js'<br>Hi my test of gsa starts here<br>xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx<br> ***Either you specified an unqualified symbol, or your debugger*** <br>xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx<br> ***Type referenced: WinMain*** <br><br>Error: Unable to bind name 'WinMain'<br>Error: Expected expression at '\"WinMain\")'<br>Error: Expected expression at '[object Object])'<br>Error: Unable to take address of object<br>Error: Unable to take address of object<br>@$scriptContents.host.evaluateExpression( "(long) 0x80000001" ),x :<br>0xffffffff80000001<br>quit:<br><br>:<br><br>On 11/11/16, xxxxx@microsoft.com <xxxxx> wrote:<br>>> [quote2]<br>>> [] well the Filter expression for lma <addr> seems to be<br>>> ok but it returns text<br>><br>> Not sure I understand what you mean by "ok but it returns text". You can<br>> think of a 'dx <expression>' as several steps:<br>><br>> 1) evaluate the expression<br>> 2) create an object for the result of the expression (or every sub-result in<br>> the evaluator)<br>> 3) use something **conceptually like** reflection to display that object to<br>> console. For example:<br>><br>> 0:000> gu<br>> USER32!GetMessageW+0x26:<br>> 00007ffb
d1cc4866 8b4b08 mov ecx,dword ptr [rbx+8]
> ds:00000040ddb0fbb8=00000200<br>> 0:000> dx @$matches = @$curprocess.Modules.Where (a=> @rip >= a.BaseAddress<br>> && @rip < a.BaseAddress + a.Size)<br>> @$matches = @$curprocess.Modules.Where (a=> @rip >= a.BaseAddress && @rip <<br>> a.BaseAddress + a.Size)<br>> [0x0] : C:\Windows\System32\USER32.dll<br>> 0:000> dx @$module = @$matches.First()<br>> @$module = @$matches.First() :<br>> C:\Windows\System32\USER32.dll<br>> BaseAddress : 0x7ffbd1ca0000<br>> Name : C:\Windows\System32\USER32.dll<br>> Size : 0x165000<br>> 0:000> dx @$baseAddr = @$module.BaseAddress<br>> @$baseAddr = @$module.BaseAddress : 0x7ffbd1ca0000<br>> 0:000> dx @$baseAddr+1000<br>> @$baseAddr+1000 : 0x7ffbd1ca03e8<br>><br>> In essence, everything evaluated (even sub-expressions) is an object. It<br>> only "turns to text" by 'dx' displaying it. Anything above can also be done<br>> directly in JavaScript:<br>><br>> function findModuleBase(addr)<br>> {<br>> var matches = host.currentProcess.Modules.Where(m => addr >=<br>> m.BaseAddress && addr < m.BaseAddress + m.Size);<br>> var module = matches.First();<br>> var baseAddr = module.BaseAddress;<br>><br>> //<br>> // baseAddr is now a 64-bit library type. You can return this from the<br>> method and it will return to the dx EE as a 64-bit unsigned value.<br>> //<br>> return baseAddr;<br>> }<br>><br>> 0:000> .load jsprovider.dll<br>> 0:000> .scriptload g:\junk\js1\modBase.js<br>> JavaScript script successfully loaded from 'g:\junk\js1\modBase.js'<br>> 0:000> .scriptload g:\junk\js1\modBase.js<br>> JavaScript script successfully loaded from 'g:\junk\js1\modBase.js'<br>> 0:000> dx @$scriptContents.findModuleBase(@rip)<br>> @$scriptContents.findModuleBase(@rip) : 0x7ffbd1ca0000<br>> 0:000> dx @$secondBase = @$scriptContents.findModuleBase(@rip)<br>> @$secondBase = @$scriptContents.findModuleBase(@rip) : 0x7ffbd1ca0000<br>> 0:000> dx @$secondBase+0x1000<br>> @$secondBase+0x1000 : 0x7ffbd1ca1000<br>><br>>> and my extension gives me<br>>><br>>> 0:000> !fnproto<br>>> no of entries = 1 13d1260<br>><br>> Out of curiousity, where is your !fnproto pulling the signature info from on<br>> the publics?<br>><br>>> are you running this on win7<br>>><br>>> yes<br>>><br>>> i changed combase.dll to ole32.dll but it still appears to be not working<br>><br>> There's more than one occurrence of combase.dll in the script. When I<br>> change all of them to ole32, it works (at least superficially) on my Win7<br>> machine. The invalid argument error happens becuase it cannot find either<br>> the module as named, the symbol as named, or the type as named. As I<br>> mentioned before, I'll try to get the sample updated to work fully and<br>> properly on Win7 and not just 8+.<br>><br>>> yeah i understood from doc that i need to provide an optional typeinfo<br>>><br>>> but when i tried it some variations like this i couldnt find any result<br>>><br>>> 0:000> dx @$scriptContents.host.getModuleSymbol("ntdll.dll" , "_PEB" ,<br>>> _PEB)<br>>> Error: Unspecified error (0x80004005)<br>><br>> The arguments to getModule symbol are as follows getModuleSymbol(moduleName,<br>> symbolName, [typeName], [contextInheritor]):<br>><br>> The first three arguments are **strings** and it returns an object which<br>> represents that **DATA** symbol. Maybe getModuleObject(...) might have been<br>> better nomenclature. You can't getModuleSymbol(...) on a type. It needs to<br>> be something which is "type + location" (e.g.: a global variable). As a few<br>> examples:<br>><br>> // Cast the thing at whatever the address of "CGIPTable::_palloc" in<br>> "ole32.dll" to "Ole32!CPageAllocator" and return the object<br>> 0:004> dx @$scriptContents.host.getModuleSymbol("ole32.dll",<br>> "CGIPTable::_palloc", "CPageAllocator")<br>> @$scriptContents.host.getModuleSymbol("ole32.dll", "CGIPTable::_palloc",<br>> "CPageAllocator") [Type: CPageAllocator]<br>> [+0x000] _pgalloc [Type: CInternalPageAllocator]<br>> [+0x050] _hHeap : 0x0 [Type: void *]<br>> [+0x058] _cbPerEntry : 0x0 [Type: unsigned __int64]<br>> [+0x060] _lNumEntries : 0 [Type: long]<br>><br>> // Cast the thing at whatever the address of "CGIPTable::_palloc" in<br>> "ole32.dll" to "tagMSG" and return the object<br>> 0:004> dx @$scriptContents.host.getModuleSymbol("ole32.dll",<br>> "CGIPTable::_palloc", "tagMSG")<br>> @$scriptContents.host.getModuleSymbol("ole32.dll", "CGIPTable::_palloc",<br>> "tagMSG") [Type: tagMSG]<br>> [+0x000] hwnd : 0x0 [Type: HWND__ *]<br>> [+0x008] message : 0x0 [Type: unsigned int]<br>> [+0x010] wParam : 0x0 [Type: unsigned __int64]<br>> [+0x018] lParam : 0 [Type:__int64]<br>> [+0x020] time : 0x0 [Type: unsigned long]<br>> [+0x024] pt [Type: tagPOINT]<br>><br>><br>> // Cast the thing at whatever the address of "CGIPTable::_palloc" in<br>> "ole32.dll" to a function of signature "int __cdecl(int, float, tagMSG)" and<br>> return the object<br>> 0:004> dx @$scriptContents.host.getModuleSymbol("ole32.dll",<br>> "CGIPTable::_palloc", "int__cdecl(int, float, tagMSG)")<br>> @$scriptContents.host.getModuleSymbol("ole32.dll", "CGIPTable::_palloc",<br>> "int __cdecl(int, float, tagMSG)") [Type: int<br>>__cdecl(int,float,tagMSG)]<br>><br>> While that above example is a bit contrived (and silly), you'll note that<br>> the DML link on what gets spit out is a DML link to disassemble and you can<br>> right click and get "Open Source File" and "Set Breakpoint [bp]" on the<br>> context menu. It's recognized as a function. Now I will point out that if<br>> what's passed in the 'symbolName' argument is indeed a function symbol<br>> (e.g.: "WinMain"), this will fail. That'll get fixed.<br>><br>> If you must presently get a function (or the address) of a function from<br>> JavaScript, you can invoke the EE (though such restricts you to C/C++<br>> language features and not LINQ, random WinDbg specific features, etc...).<br>> For example:<br>><br>> function getSymbolAddr(sym)<br>> {<br>> return host.evaluateExpression("(unsigned __int64)(&" + sym + ")");<br>> }<br>><br>> 0:000> u notepad!WinMain<br>> notepad!WinMain<br>> 00007ff6
ac283b1c 48895c2410 mov qword ptr [rsp+10h],rbx
>
> 0:000> dx @$scriptContents.getSymbolAddr(âWinMainâ)
> @$scriptContents.getSymbolAddr(âWinMainâ) : 0x7ff6ac283b1c
>
> Hope that helps to clear things up!
>
> â
> WINDBG is sponsored by OSR
>
> OSR is hiring!! Info at http://www.osr.com/careers
>
>
> MONTHLY seminars on crash dump analysis, WDF, Windows internals and software
> drivers!
> Details at http:
>
> To unsubscribe, visit the List Server section of OSR Online at
> http:
></http:></http:>