|
|
/*++
Copyright (c) Microsoft Corporation. All rights reserved.
Module Name:
Extend.cpp
Abstract:
Contains a list of extended bad functions. These are not compatibility problems, but can be used for training purposes.
Notes:
ANSI only - must run on Win9x.
History:
05/16/01 rparsons Created 01/10/02 rparsons Revised
--*/ #include "demoapp.h"
extern APPINFO g_ai;
/*++
Routine Description:
Performs a simple access violation.
Arguments:
None.
Return Value:
None.
--*/ void AccessViolation( void ) { // We could perform hundreds of different operations to get an
// access violation. The one below attempts to copy the string
// 'foo' to a NULL address.
memcpy(NULL, "foo", 3);
/* Here's another:
WCHAR szArray[10]; int nCount = 0;
for (nCount = 0; nCount != 12; nCount++) { wcscpy((LPWSTR)szArray[nCount], L"A"); }*/ }
/*++
Routine Description:
Throws a EXCEPTION_ARRAY_BOUNDS_EXCEEDED exception.
Arguments:
None.
Return Value:
None.
--*/
//
// Disable the warning: 'frame pointer register 'ebp' modified by
// inline assembly code. We're doing this intentionally.
//
#pragma warning( disable : 4731 )
void ExceedArrayBounds( void ) { _asm { push ebp; // Save the base pointer
mov ebp, esp; // Set up the stack frame
sub esp, 8; // Adjust for 8 bytes worth of
// local variables
push ebx; // Save EBX for later
mov dword ptr [ebp-8], 1; // Initialize a DWORD to 1
mov dword ptr [ebp-4], 2; // Initialize a DWORD to 2
mov eax, 0; // Zero out EAX
bound eax, [ebp-8]; // If [ebp-8] is out of EAX bounds,
// an exception will occur
xor eax, eax; // Zero out EAX
pop ebx; // Restore EBX from earlier
mov esp, ebp; // Restore the stack frame
pop ebp; // Restore the base pointer
ret; // We're done
} }
#pragma warning( default : 4731 )
/*++
Routine Description:
Frees memory allocated from the heap twice.
Arguments:
None.
Return Value:
None.
--*/ void FreeMemoryTwice( void ) { LPSTR lpMem = NULL;
lpMem = (LPSTR)HeapAlloc(GetProcessHeap(), 0, MAX_PATH);
if (!lpMem) { return; }
HeapFree(GetProcessHeap(), 0, lpMem); HeapFree(GetProcessHeap(), 0, lpMem); }
/*++
Routine Description:
Allocates memory from the heap, moves the pointer, then tries to free it.
Arguments:
None.
Return Value:
None.
--*/ void FreeInvalidMemory( void ) { LPSTR lpMem = NULL;
lpMem = (LPSTR)HeapAlloc(GetProcessHeap(), 0, MAX_PATH);
if (!lpMem) { return; }
lpMem++; lpMem++;
HeapFree(GetProcessHeap(), 0, lpMem); }
/*++
Routine Description:
Executes a privileged instruction, which causes an exception.
Arguments:
None.
Return Value:
None.
--*/ void PrivilegedInstruction( void ) { _asm { cli; } }
/*++
Routine Description:
Allocates memory from the heap, then walks all over it.
Arguments:
None.
Return Value:
None.
--*/ void HeapCorruption( void ) { UINT n, nTotalChars; char szCorruptChars[] = {'B','A','D','A','P','P','#'}; char* pChar = NULL; //
// Allocate a small block of heap to contain a string of length STRINGLENGTH.
//
pChar = (char*)GlobalAlloc(GPTR, 13); if (!pChar) { return; } else { //
// Determine the total number of chars to copy (including Corrupt Bytes)
//
nTotalChars = 12 + 1; //
// Write a string of STRINGLENGTH length, plus some extra (common mistake).
//
for (n = 0; n < nTotalChars; n++) { //
// Write the characters of CorruptChars into memory.
//
if (n < (UINT)12) { pChar[n] = szCorruptChars[n % 6]; } else { //
// Corruption will be written with a nice pattern of # chars...
//
pChar[n] = szCorruptChars[6]; } }
//
// Of course, we should NULL terminate the string.
//
pChar[n] = 0;
GlobalFree((HGLOBAL)pChar); } }
/*++
Routine Description: Launches a child process (version.exe) which is embedded within our DLL. Arguments: cchSize - Size of the output buffer in characters. pszOutputFile - Points to a buffer that will be filled with the path to the output file. Return value: On success, pszOutputFile points to the file. On failure, pszOutputFile is NULL. --*/ void ExtractExeFromLibrary( IN DWORD cchSize, OUT LPSTR pszOutputFile ) { HRSRC hRes; HANDLE hFile; HRESULT hr; HGLOBAL hLoaded = NULL; BOOL bResult = FALSE; HMODULE hModule = NULL; PVOID pExeData = NULL; DWORD cbFileSize, cbWritten, cchBufSize;
__try { //
// Find the temp directory and set up a path to
// the file that we'll be creating.
//
cchBufSize = GetTempPath(cchSize, pszOutputFile); if (cchBufSize > cchSize || cchBufSize == 0) { __leave; } hr = StringCchCat(pszOutputFile, cchSize, "version.exe"); if (FAILED(hr)) { __leave; }
//
// Obtain a handle to the resource and lock it so we can write
// the bits to a file.
//
hModule = LoadLibraryEx("demodll.dll", NULL, LOAD_LIBRARY_AS_DATAFILE); if (!hModule) { __leave; } hRes = FindResource(hModule, (LPCSTR)105, "EXE"); if (!hRes) { __leave; } cbFileSize = SizeofResource(hModule, hRes);
if (cbFileSize == 0) { __leave; } hLoaded = LoadResource(hModule, hRes);
if (!hLoaded) { __leave; }
pExeData = LockResource(hLoaded); if (!pExeData) { __leave; } hFile = CreateFile(pszOutputFile, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (INVALID_HANDLE_VALUE == hFile) { __leave; } WriteFile(hFile, (LPCVOID)pExeData, cbFileSize, &cbWritten, NULL); CloseHandle(hFile);
bResult = TRUE; } // __try
__finally { if (hModule) { FreeLibrary(hModule); }
if (hLoaded) { UnlockResource(hLoaded); }
if (!bResult) { *pszOutputFile = 0; } } }
|