Skip to content

Commit

Permalink
Flash fix:
Browse files Browse the repository at this point in the history
When flash was first used on Windows then console windows with "echo NOT SANDBOXED" flickered.
  • Loading branch information
janRucka committed Mar 3, 2017
1 parent 9ed150d commit eda1803
Showing 1 changed file with 143 additions and 0 deletions.
143 changes: 143 additions & 0 deletions base/native_library_win.cc
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,152 @@
#include <windows.h>

#include "base/files/file_util.h"
#include "base/path_service.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/threading/thread_restrictions.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/logging_chrome.h"

namespace base {

typedef HMODULE (WINAPI* LoadLibraryFunction)(const wchar_t* file_name);

namespace {

PROC g_orig_create_process = NULL;
HINSTANCE flash_dll;

bool IsValidDosHeader(PIMAGE_DOS_HEADER dosHeader) {
if (IsBadReadPtr(dosHeader, sizeof(IMAGE_DOS_HEADER)))
return false;

if (dosHeader->e_magic != IMAGE_DOS_SIGNATURE)
return false;

return true;
}

bool IsValidNTHeader(PIMAGE_NT_HEADERS ntHeader) {
if (IsBadReadPtr(ntHeader, sizeof(PIMAGE_NT_HEADERS)))
return false;

if (ntHeader->Signature != IMAGE_NT_SIGNATURE)
return false;

return true;
}

BOOL WINAPI ReplaceFunctionAddressInModule(HMODULE module, PROC origFunc, PROC newFunc) {
if (!module || !newFunc || !origFunc || IsBadCodePtr(newFunc))
return FALSE;

PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)module;
if (!IsValidDosHeader(dosHeader))
return FALSE;

// Find the NT Header by using the offset of e_lfanew value from hMod
PIMAGE_NT_HEADERS ntHeader = (PIMAGE_NT_HEADERS)((DWORD)dosHeader + (DWORD)dosHeader->e_lfanew);
if (!IsValidNTHeader(ntHeader))
return FALSE;

PIMAGE_IMPORT_DESCRIPTOR importDesc = (PIMAGE_IMPORT_DESCRIPTOR)((DWORD)dosHeader +
(DWORD)(ntHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress));

if (importDesc == (PIMAGE_IMPORT_DESCRIPTOR)ntHeader)
return FALSE;

while (importDesc->Name) {
char *moduleName = (char *)((DWORD)dosHeader + (DWORD)(importDesc->Name));
if (_stricmp(moduleName, "kernel32.dll") == 0) {
PIMAGE_THUNK_DATA thunkData = (PIMAGE_THUNK_DATA)((DWORD)dosHeader + (DWORD)importDesc->FirstThunk);
while (thunkData->u1.Function) {
// get the pointer of the imported function and see if it matches up with the original
if ((DWORD)thunkData->u1.Function == (DWORD)origFunc) {
MEMORY_BASIC_INFORMATION mbi;
DWORD oldProt;
VirtualQuery(&thunkData->u1.Function, &mbi, sizeof(MEMORY_BASIC_INFORMATION));
VirtualProtect(mbi.BaseAddress, mbi.RegionSize, PAGE_READWRITE, &oldProt);
thunkData->u1.Function = (DWORD)newFunc;
VirtualProtect(mbi.BaseAddress, mbi.RegionSize, oldProt, &oldProt);
break;
} else {
++thunkData;
}
}
}
++importDesc;
}
return TRUE;
}

BOOL WINAPI MyCreateProcessA(
_In_opt_ LPCSTR lpApplicationName,
_Inout_opt_ LPSTR lpCommandLine,
_In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes,
_In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes,
_In_ BOOL bInheritHandles,
_In_ DWORD dwCreationFlags,
_In_opt_ LPVOID lpEnvironment,
_In_opt_ LPCSTR lpCurrentDirectory,
_In_ LPSTARTUPINFOA lpStartupInfo,
_Out_ LPPROCESS_INFORMATION lpProcessInformation
) {
if (g_orig_create_process != NULL &&
strstr(lpCommandLine, "cmd.exe /c echo NOT SANDBOXED") != NULL) {
LOG(INFO) << "Prevent flash from calling: echo NOT SANDBOXED";
HINSTANCE libInstance = LoadLibrary(TEXT("kernel32.dll"));
g_orig_create_process = GetProcAddress(libInstance, "CreateProcessA");
ReplaceFunctionAddressInModule(flash_dll,
GetProcAddress(libInstance, "CreateProcessA"), g_orig_create_process);
g_orig_create_process = NULL;
return TRUE;
}

typedef BOOL(*CREATE_PROC) (
LPCSTR,
LPSTR,
LPSECURITY_ATTRIBUTES,
LPSECURITY_ATTRIBUTES,
BOOL,
DWORD,
LPVOID,
LPCSTR,
LPSTARTUPINFOA,
LPPROCESS_INFORMATION
);

CREATE_PROC createProc = (CREATE_PROC)g_orig_create_process;
return createProc(
lpApplicationName,
lpCommandLine,
lpProcessAttributes,
lpThreadAttributes,
bInheritHandles,
dwCreationFlags,
lpEnvironment,
lpCurrentDirectory,
lpStartupInfo,
lpProcessInformation
);
}

void SetCreateProcessProxy(HINSTANCE module) {
HINSTANCE libInstance = LoadLibrary(TEXT("kernel32.dll"));
g_orig_create_process = GetProcAddress(libInstance, "CreateProcessA");
ReplaceFunctionAddressInModule(module, GetProcAddress(libInstance, "CreateProcessA"), PROC(MyCreateProcessA));
}

bool IsFlash(const FilePath& library_path) {
base::FilePath flash_filename;
if (!PathService::Get(chrome::FILE_PEPPER_FLASH_SYSTEM_PLUGIN,
&flash_filename))
return false;

return flash_filename == library_path;
}

NativeLibrary LoadNativeLibraryHelper(const FilePath& library_path,
LoadLibraryFunction load_library_api,
NativeLibraryLoadError* error) {
Expand All @@ -42,6 +177,14 @@ NativeLibrary LoadNativeLibraryHelper(const FilePath& library_path,
error->code = GetLastError();
}

if (module) {
if (IsFlash(library_path)) {
flash_dll = module;
// to prevent flickering
SetCreateProcessProxy(module);
}
}

if (restore_directory)
SetCurrentDirectory(current_directory);

Expand Down

0 comments on commit eda1803

Please sign in to comment.