Jul. 23rd, 2009

sergey_cheban: (Default)
Как известно, программы, собранные с помощью MSVC2005 (или, если угодно, с помощью Platform SDK for Vista), не работают под Win95. А иногда, к сожалению, надо.
В чём дело? Дело в том, что CRT в некоторых случаях вызывает функцию IsDebuggerPresent(), которая должна быть в kernel32.dll. Поскольку под Win95 её там нет, программа просто не загружается.

Как лечить? Очень просто:

1. Берём исходник:
======================================================================================
.386
.MODEL FLAT

EXTERN __imp__GetModuleHandleA@4:DWORD
EXTERN __imp__GetProcAddress@8:DWORD

.data
Kernel32LibName db "kernel32.dll", 0
IsDebuggerPresentName db "IsDebuggerPresent", 0

.code
IsDebuggerPresent95 PROC STDCALL
push offset Kernel32LibName
call dword ptr [__imp__GetModuleHandleA@4]
or eax, eax
jne $1
ret
$1:
push offset IsDebuggerPresentName
push eax
call dword ptr [__imp__GetProcAddress@8]
or eax, eax
jne $2
ret
$2:
jmp eax
IsDebuggerPresent95 ENDP

.data
__imp__IsDebuggerPresent@0 DWORD IsDebuggerPresent95

PUBLIC __imp__IsDebuggerPresent@0

END
======================================================================================

2. Пишем его в файл "IsDebuggerPresent.asm_".
3. Добавляем этот файл в проект.
4. Прописываем custom build:
Command line: ml.exe /c /nologo /Fo"$(IntDir)\$(InputName).obj_" /W3 /Zi /errorReport:prompt /Ta $(InputFileName)
Outputs: $(IntDir)\$(InputName).obj_
5. Линкеру в Additional dependencies прописываем $(IntDir)\IsDebuggerPresent.obj_

Пункты 4 и 5 нужны, чтобы IsDebuggerPresent.obj_ был передан линкеру ровно один раз, причём перед kernel32.lib.

В результате из CRT вызывается наша функция IsDebuggerPresent95, которая пытается найти оригинальную IsDebuggerPresent в kernel32.dll, и если находит, то передаёт управление ей.
Page generated Jul. 25th, 2025 05:49 am
Powered by Dreamwidth Studios