The problem
For now it is very easy to obtain access violation in WIN32 platform, when we try to read bios memory address. It is for this that virtual machines provide memory protection, virtual memory, and privilege checking. If an application in a virtual machine reads or writes memory addresses that has not been mapped into its virtual machine or manipulates Bios Interrupts to which it has not been allowed access, an exception (fault) is generated, and the VMM regains control.
The solution
Ok, this program is only one option for trying to get Bios date in WIN32 platform. For that, I wrote a console program, created for 16 bit compilers, using VC++ 1.0 | BC++ 4.0 | Turbo C++ 3.0. This program generates a file with Bios date.
Other 32-bit Windows-based applications, execute this 16-bit console process in a synchronous way and hidden mode. This means that, first we create the process and then kill the process. For this I use the functions CreateProcess()
for creation and TerminateProcess()
for kill, respectively. For synchronous process, the function WaitForSingleObject(m_hProcess, INFINITE)
, and ready.
16-bit console process
Bios date is stored in 8 bytes starting from address F000:FFF5
, using ASCII character. To read this address we can use the function peek(...)
and poke(...)
of BC++ 4.0 library or in another case use the function below. This function returns the contents of the specified memory location segment:offset
.
unsigned char pekAux(unsigned int segment, unsigned int offset)
{
unsigned char _far *ptr;
ptr = (unsigned char _far *)(((long)segment << 16) | (long)offset);
return *ptr;
}
32-bit Windows-based application
Here we execute and HIDE the 16-bit console process
void CBiosDateDlg::StartProcess(char* lpszFileName)
{
BOOL bWorked;
STARTUPINFO suInfo;
PROCESS_INFORMATION procInfo;
char *m_Process = lpszFileName;
char *vip = lpszFileName;
memset (&suInfo, 0, sizeof(suInfo));
suInfo.cb = sizeof(suInfo);
suInfo.lpReserved = NULL;
suInfo.lpDesktop = "";
suInfo.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
suInfo.wShowWindow = SW_HIDE;
bWorked = CreateProcess(m_Process,
NULL,
NULL,
NULL,
TRUE,
REALTIME_PRIORITY_CLASS,
NULL,
NULL,
&suInfo,
&procInfo);
if (procInfo.dwThreadId = NULL)
{
ExitProcess(1);
}
m_hProcess = procInfo.hProcess;
m_dwProcessPid = procInfo.dwProcessId;
}
Then wait for the end process, using function:
WaitForSingleObject(m_hProcess, INFINITE);
and kill process.
void CBiosDateDlg::KillProcess()
{
HANDLE ps = OpenProcess( SYNCHRONIZE|PROCESS_QUERY_INFORMATION,
TRUE, m_dwProcessPid);
TerminateProcess(ps, 1);
CloseHandle(ps);
}
That's it
If somebody has some idea or article, with respect to reading Bios address memory in WIN32 platform, avoiding message exception and access violation, please don't doubt to send me your suggestions, I will be grateful.
Thanks my friends.
Hobies: Salir de paseo con mi Hijo Josue, tocar el piano, desarrollar en ever in C++