Easyhook 32-битное приложение
Я использую EasyHook для перехвата вызовов реестра. Более подробно, я использую RegQueryValue, чтобы перехватить вызов, который читает ключ из реестра и изменить его значение на что-то другое. Соответствующий код выглядит так:
[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);
}
Если я собираю все с target x64, все это выполняется без проблем.
Однако, если я собираю его с целью x32, он вылетает в RegQueryValueExW_Hooked с ошибкой:
Необработанное исключение: System.Runtime.InteropServices.SEHException: внешний компонент выдал исключение. at DummyDCA.Program.Main(String[] args) Необработанное исключение: System.ArgumentOutOfRangeException: емкость превышает максимальную емкость. Имя параметра: емкость в AG.RU.Valuation.Controller.AFMToolbox.Inject.Main.RegQueryValueExW(IntPtrhKey, String lpValueName, Int32 lpReserved, RegistryValueKind& lpType, StringBuilder lpDataToLBT..Main.RegQueryValueExW_Hooked(IntPtr hKey, String lpValueName, Int32 lpReserved, RegistryValueKind& lpType, StringBuilder lpData, Int32& lpcbData)
Кажется, проблема в lpData типа StringBuilder (какое-то переполнение, StringBuilder недостаточно велик или что-то в этом роде). Если я заменю StringBuilder на IntPtr, он не вылетает; но тогда у меня есть указатель, а не StringBuilder, поэтому я не уверен, как я могу заменить значение lpData.
У кого-нибудь есть идея, почему это так и как это нужно делать?
Спасибо!
1 ответ
Казалось, что вместо StringBuilder мне пришлось использовать IntPtr; и реализация RegQueryValueExW_Hooked также была немного особенной.
Фактическое решение описано Luaan в этой теме: изменение строки, на которую указывает IntPtr