64-битный код обнаружения VMWare запускает точку остановаC#

Место общения программистов C#
Ответить
Anonymous
 64-битный код обнаружения VMWare запускает точку останова

Сообщение Anonymous »

Я выполняю обнаружение VMWare в консольном проекте .NET 2.0 C#. Код обнаружения реализован на языке C как экспортированная функция в DLL, которая вызывается из кода C# с помощью P/Invoke. Код C# компилируется как x86 и x64 в два отдельных исполняемых файла. C DLL также скомпилирована для обеих платформ. Вот экспортированная функция:

Код: Выделить всё

PUBLIC Int32 __declspec(nothrow) WINAPI GetVMType ()
{
Int32 nVMWareType = 0;

try
{
if ( !IsInVMWare ( nVMWareType ) )
{
... // allocate memory, write data, etc.
}
}
catch ( ... )
{
nVMWareType = -1;
}

return ( nVMWareType );
} //  0 )
bResult = true;
}
__except ( EXCEPTION_EXECUTE_HANDLER )
{
bResult = false;
}

return ( bResult );
}
64-битный код обнаружения реализован как GetVMWareVersion() на ассемблере:

Код: Выделить всё

PUBLIC GetVMWareVersion
.CODE
ALIGN   8

GetVMWareVersion PROC

push    rbp
mov     rbp, rsp

push    rdx
push    rcx
push    rbx

mov     rax, 'VMXh'
mov     rbx, 0       ; anything but 'VMXh'
mov     rcx, 10      ; get VMWare version
mov     rdx, 'VX'    ; port number
in      rax, dx      ; read port
cmp     ebx, 'VMXh'  ; is it a reply from VMWare?
je      $0@GetVMWareVersion

xor     rax, rax     ; not in VMWare - clear return value
jmp     $1@GetVMWareVersion

$0@GetVMWareVersion:
mov     rax, rcx     ; VMWare product type

$1@GetVMWareVersion:
pop     rbx
pop     rcx
pop     rdx

mov     rsp, rbp
pop     rbp
ret

GetVMWareVersion ENDP

END
32-разрядный код обнаружения отлично работает на Windows 7, отличной от виртуальной машины. При запуске 64-разрядной версии (та же среда) он запускает вызов DebugBreak() со следующим стеком вызовов:

Код: Выделить всё

KernelBase.dll!DebugBreak() + 0x2 bytes
[Frames below may be incorrect and/or missing, no symbols loaded for KernelBase.dll]
mscorwks.dll!PreBindAssembly() + 0x9ce69 bytes
mscorwks.dll!PreBindAssembly() + 0x9d28e bytes
mscorwks.dll!CreateApplicationContext() + 0x769d bytes
mscorwks.dll!StrongNameTokenFromPublicKey() + 0x64f8 bytes
mscorwks.dll!StrongNameTokenFromPublicKey() + 0x66ff bytes
mscorwks.dll!CreateApplicationContext() + 0x7f62 bytes
ntdll.dll!vsprintf_s() + 0x12b bytes
ntdll.dll!RtlUnwindEx() + 0x852 bytes
ntdll.dll!KiUserExceptionDispatcher() + 0x2e bytes
mscorwks.dll!IEE() + 0xd285 bytes
cccccccccccccccc()
0000000000d78180()
cccccccccccccccc()
У меня также есть это в окне вывода, когда я отлаживаю C DLL в Visual Studio:

Код: Выделить всё

First-chance exception at 0x000007feedbdfad1 (mscorwks.dll) in MyApp.exe:
0xC0000005: Access violation reading location 0xffffffffffffffff.
Время от времени (не всегда) я также получаю это в журнале событий:

Код: Выделить всё

.NET Runtime version 2.0.50727.5456 - Fatal Execution Engine Error
(000007FEEDB27916) (80131506)
Я совершенно не понимаю, почему это происходит. Я много искал, но не смог найти ничего, что могло бы относиться к этой проблеме. Некоторые сайты предлагают перейти на .NET 4.0, но это не вариант.

Я проанализировал весь код в GetVMType() — он выделяет некоторую память и записывает данные в динамически выделяемые массивы, но этот код правильный: вся память освобождается и никакая память не перезаписывается неправильно.

Если я изменю 64-битный ассемблерный код, чтобы пропустить инструкцию in, точка останова не будет сработало. Это не проблема при запуске 32-битного кода.

Вызывающая программа C# имеет обработчик исключений верхнего уровня и обработчик событий для события UnhandledException, но когда возникает эта проблема, приложение просто завершает работу - ни один из обработчиков не вызывается.

Кто-нибудь знает, что может быть не так с этой настройкой? Я потратил часы на отладку и пытался понять, что происходит, но кажется, что что-то внутри .NET ломается, когда вызов P/Invoke возвращается после выполнения инструкции in.

Подробнее здесь: https://stackoverflow.com/questions/132 ... breakpoint
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»