Sunday, July 20, 2014

Memory management of BSTR objects in COM

When working with BSTR with COM objects, the following questions have to be answered:
1. When passing BSTR to a COM object, who is responsible to free the memory allocated to BSTR?
2. When a COM object returns BSTR, who is responsible to free the memory allocated to BSTR?

Answer to both these questions is: caller of the COM object is responsible for freeing memory allocated to BSTR.

Examples:
1. When passing BSTR to COM object
Solution:
    {
            CComPtr<IComDog> dog;
            dog.CoCreateInstance(Animals::CLSID_Dog);
            BSTR nameOfDog = SysAllocString(L"Tiger");
            dog->put_NameOfDog(nameOfDog);
            .....
            // other code for dogs
            .....
            SysFreeString(nameOfDog);
            nameOfDog = NULL;
    }

Instead of using BSTR directly, use CComBSTR which takes care of memory management.
    {
            CComPtr<IComDog> dog;
            dog.CoCreateInstance(Animals::CLSID_Dog);
            CComBSTR nameOfDog = L"Tiger";
            dog->put_Name(nameOfDog);
            .....
            // other code for dogs
            // free'ing memory allocated to nameOfDog is taken care of by CComPtr
     }

2. When COM return a BSTR
     TBD

Wednesday, July 16, 2014

PowerShell Script to find Process IDs of an Executable

To find the priority of Threads of a process, copy the following script and execute in PowerShell

$timeoutInSeconds = 100;
$processName = "myExecutable.exe"

$processList = Get-WmiObject win32_process | where { $_.ProcessName -eq "$processName" } | select Handle
foreach ($processIds in $processList)
{
    $processId = $processIds.Handle
    Write-Host "process id = $processId"
}


Disclaimer: Use at your own risk. The author does not take any responsibility for the behavior of this script.

Lock Windows Desktop during Remote Session

In order to lock a Windows desktop during remote session, execute the following command

rundll32.exe user32.dll,LockWorkStation

Common WinDbg commands

How to set Symbol path
srv*c:\symbols*http://msdl.microsoft.com/download/symbols;
srv*c:\symbols*c:\temp\localsymbols;
srv*c:\symbols*\\network_share\symbols;

or
set environment variable name: _NT_SYMBOL_PATH
set environment variable value: srv*c:\symbols*http://msdl.microsoft.com/download/symbols;
                     srv*c:\symbols*c:\temp\localsymbols; srv*c:\symbols*\\network_share\symbols;


How to load Wow64 on x64 debugger
.load wow64exts

Other commands
lml
.ecxr
!analyze -v

How to verify if the module and pdb are a match
!itoldyouso <ModuleName> <ModulePDB>

Setup WinDbg as Postmortem Debugger
windbg -I

Setup ProcMon as Postmortem Debugger
procmon -i -ma

Redirect output to a log file
000> .logopen c:\temp\hello.txt
000> <do what ever commands> - all output is shown in windbg window and redirected to log file
000> .logclose

Find machine name (.NET dmp)
kd> x srv!SrvComputerName
fffff880`06ec4540 srv!SrvComputerName = <no type information>
kd> dq fffff880`06ec4540
fffff880`06ec4540  00000000`001a001a fffff8a0`02441df0
fffff880`06ec4550  00000000`00000000 00000000`00000000
fffff880`06ec4560  00000000`00000000 00000000`000c000a
...
kd> du fffff8a0`02441df0
fffff8a0`02441df0  "ABC"


Read GUID from a PDB using WinDbg

Here are the steps for reading GUID of a PDB

1. Install WinDbg
2. Set symbol path to the location of PDB
3. Load any executable into WinDbg
4. Execute in WinDbg 'ld <ModuleName>'
5. Execute in WinDbg '!chksym <ModuleName>
    c:\temp\<name_of_module>.dll
    Timestamp: 53FEA125
    SizeOfImage: DE000
    pdb: c:\temp\sample.pdb
    pdb sig: aaaaaaaa-bbbb-bbbb-bbbb-aaaaaaaaaaaa
    age: 1

Kill Remote Process using PowerShell

Here are the steps to kill a process running on remote machine

1. Start PowerShell
2. $processes = Get-WmiObject -class win32_process -ComputerName <name_of_computer> -Filter "Name='notepad.exe'"
3. $x = $processes.terminate()
4. echo $x

Return value should be 0