Question

I'm using EasyHook to intercept registry calls. In more detail, I use RegQueryValue to intercept the call that reads a key from registry and change its value with something else. The relevant code looks like:

[UnmanagedFunctionPointer(CallingConvention.StdCall, CharSet = CharSet.Unicode, SetLastError = true)]
delegate int DRegQueryValueExW(
    IntPtr hKey,
    string lpValueName,
    int lpReserved,
    ref Microsoft.Win32.RegistryValueKind lpType,
    StringBuilder lpData,
    ref int lpcbData);

[DllImport("Advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true, CallingConvention = CallingConvention.StdCall)]
static extern int RegQueryValueExW(
    IntPtr hKey,
    string lpValueName,
    int lpReserved,
    ref Microsoft.Win32.RegistryValueKind lpType,
    StringBuilder lpData,
    ref int lpcbData);

int RegQueryValueExW_Hooked(
    IntPtr hKey,
    string lpValueName,
    int lpReserved,
    ref Microsoft.Win32.RegistryValueKind lpType,
    StringBuilder lpData,
    ref int lpcbData)
{
    // todo: change value of lpData and return 0
    return RegQueryValueExW(hKey, lpValueName, lpReserved, ref lpType, lpData, ref lpcbData);                  
}

If I build everything with target x64, this all executes without a problem.

However, if I build it with target x32, it crashes in RegQueryValueExW_Hooked with the error:

Unhandled Exception: System.Runtime.InteropServices.SEHException: External component has thrown an exception. at DummyDCA.Program.Main(String[] args) Unhandled Exception: System.ArgumentOutOfRangeException: Capacity exceeds maximum capacity. Parameter name: capacity at AG.RU.Valuation.Controller.AFMToolbox.Inject.Main.RegQueryValueExW(IntPtrhKey, String lpValueName, Int32 lpReserved, RegistryValueKind& lpType, StringBuilder lpData, Int32& lpcbData) at AG.RU.Valuation.Controller.AFMToolbox.Inject.Main.RegQueryValueExW_Hooked(IntPtr hKey, String lpValueName, Int32 lpReserved, RegistryValueKind& lpType, StringBuilder lpData, Int32& lpcbData)

The problem seems to be lpData of type StringBuilder (some kind of overflow, the StringBuilder is not large enough or something). If I replace StringBuilder with IntPtr, it doesn't crash; but then I have a pointer and not a StringBuilder, so I'm not sure how I can replace the value of lpData.

Does anyone have an idea why this is, and how it should be done?

Thanks!

Was it helpful?

Solution

It seemed that instead of StringBuilder, I had to use IntPtr; and the implementation of RegQueryValueExW_Hooked also was a bit special.

The actual solution is described by Luaan in this thread: Changing the string to which an IntPtr is pointing

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top