x86/x64 MSVC plugins

January 26, 2013 – 2:50 am

Recently I had to write a tiny MSVC plugin to help visualizing one of our structures. It’s been a while since I’ve done it last time, so I started Googling for help. The good news is — it’s now much easier to find information/articles (mostly unofficial). The bad news — there are still many dark corners & I ran into a problem that took me a while to figure out.
Our game runs both in 32-bit (x86) & 64-bit mode (x64, we have two executables). I wanted my plugin to work with both, which might be tricky if your structures contain pointers. Example:

struct Foo
{
    void* data;
    Bar bar;
};

Now, imagine we’d like to get information about ‘bar’ member (given Foo pointer), offset will be different in x64/x86 builds. Luckily, there’s a method in DEBUGHELPER class that lets us retrieve configuration — GetProcessorType. Sample usage:

template<typename PtrType>
struct Foo
{
    PtrType    data;
    Bar        bar;
};
//DEBUGHELPER *pHelper
enum MPT
// stolen from https://github.com/dawgfoto/cv2pdb/blob/master/src/dviewhelper/dviewhelper.cpp
{
    MPT_X86 = 0,
    MPT_IA64,
    MPT_AMD64,
    MPT_Unknown
};
const int cpuType = pHelper->GetProcessorType(pHelper);
DWORD bytesRead(0);
const DWORD bytesToRead = (cpuType == MPT_X86 ? sizeof(Foo<uint32>) : sizeof(Foo<__int64>));
Foo<__int64> foo; // bigger type by default (also -- stricter alignment reqs)
if (pHelper->ReadDebuggeeMemoryEx(pHelper, pHelper->GetRealAddress(pHelper),
    bytesToRead, &foo, &bytesRead) != S_OK || bytesRead != bytesToRead)
{
    return E_FAIL;
}
Bar* bar = &foo.bar;
if(cpuType == MPT_X86)
{
    Foo<uint32>* ff32 = reinterpret_cast<Foo<uint32>* >(&foo);
    bar = &ff32->bar;
}
// Process bar now, it's pointing to a correct location both for 32 & 64 bit builds.
  1. One Response to “x86/x64 MSVC plugins”

  2. Thanks for sharing! I’m sure this will save someone else a bunch of time and frustration :)

    By Karl Schmidt on Jan 30, 2013

Post a Comment