Hемного теории:
VxD очень сильно отличаются от обычных win32/win16/DOS-приложений. VxD, как правило, находятся в спящем состоянии, пока обычные приложения занимаются своим делом. Они поступают как наблюдатели, которые надзирают за другими ring3-приложения и корректируют их, когда они делают что-нибудь неправильно.
- Происходит прерывание
- VMM получает контроль
- VMM сохраняет значения регистров
- Сервисы VMM вызывают другие VxD
- VMM возвращает контроль прерванной программе
Самым интересным из вышесказанного является то, что VMM может оказывать влияние на прерванные приложения только одним образом - модифицируя сохраненные значения регистров. Hапример, если VMM считает, что прерванная программа должна продолжить выполнение с другого адреса, она может поменять значение CS:IP (значения которых были сохранены до прерывания программы), что повлечет за собой изменение хода программы - она продолжит выполнение по новому адресу, содержащемуся в CS:IP.
VMM сохраняет значения регистров в месте прерывания программы в CRS.
Client_Reg_Struc STRUC
Client_EDI DD ? Client_ESI DD ? Client_EBP DD ? Client_res0 DD ? Client_EBX DD ? Client_EDX DD ? Client_ECX DD ? Client_EAX DD ? Client_Error DD ? Client_EIP DD ? Client_CS DW ? Client_res1 DW ? Client_EFlags DD ? Client_ESP DD ? Client_SS DW ? Client_res2 DW ? Client_ES DW ? Client_res3 DW ? Client_DS DW ? Client_res4 DW ? Client_FS DW ? Client_res5 DW ? Client_GS DW ? Client_res6 DW ? Client_Alt_EIP DD ? Client_Alt_CS DW ? Client_res7 DW ? Client_Alt_EFlags DD ? Client_Alt_ESP DD ? Client_Alt_SS DW ? Client_res8 DW ? Client_Alt_ES DW ? Client_res9 DW ? Client_Alt_DS DW ? Client_res10 DW ? Client_Alt_FS DW ? Client_res11 DW ? Client_Alt_GS DW ? Client_res12 DW ?
Client_Reg_Struc ENDS
Вы можете видеть, что в этой структуре два множества параметров:
Client_xxx и Client_Alt_xxx. Это требует небольшого объяснения. В данном VM существует две ветви выполнения: V86 и защищенного pежима. Если прерывание происходит , когда активна V86-программа, параметры Client_xxx будут содержать значения регистров V86-программы, а Client_Alt_xxx будут содержать значения регистров PM-программы. И наоборот, если прерывание происходит, когда активна PM-программа, Client_xxx будут содержать значения регистров PM-программы, а Client_Alt_xxx будут содержать значения регистров V86-программы. Client_resX зарезервированы и не используются.
У вас может появиться вопрос после анализа структуры: что если я хочу изменить только байт в структуре, например al? Вышеприведенная структура включает регистры размером только в слово и двойное слово. Hе пугайтесь. Взгляните на vmm.inc. Есть две дополнительные структуры специально для этой цели: Client_Word_Reg_Struc и Client_Byte_Reg_Struc. Если вы хотите получить доступ к регистрам размерам в слово и байт, приведите Client_Word_reg_Struc к Client_Word_Reg_Struc или Client_Byte_Reg_Struc соответственно.
Следующий вопрос: как мы можем получить указатель на CRS?
Это довольно просто: большую часть времени VMM держит адрес CRS и ebр, когда она вызывает наш VxD. CRS в этом случае описывает состояние текущей виртуальной машины. Также вы можете получить этот указатель из VM-хэндла. Помните, что хэндл VM - это линейный адрес контрольного блока VM.
cb_s STRUC CB_VM_Status DD ? CB_High_Linear DD ? CB_Client_Pointer DD ? CB_VMID DD ? CB_Signature DD ? cb_s ENDS