⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ldr.c

📁 winNT技术操作系统,国外开放的原代码和LIUX一样
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 * @implemented
 */
DWORD
STDCALL
GetModuleFileNameW (
	HINSTANCE	hModule,
	LPWSTR		lpFilename,
	DWORD		nSize
	)
{
	UNICODE_STRING FileName;
	PLIST_ENTRY ModuleListHead;
	PLIST_ENTRY Entry;
	PLDR_DATA_TABLE_ENTRY Module;
	PPEB Peb;
	ULONG Length = 0;

	Peb = NtCurrentPeb ();
	RtlEnterCriticalSection (Peb->LoaderLock);

	if (hModule == NULL)
		hModule = Peb->ImageBaseAddress;

	ModuleListHead = &Peb->Ldr->InLoadOrderModuleList;
	Entry = ModuleListHead->Flink;
	while (Entry != ModuleListHead)
	{
		Module = CONTAINING_RECORD(Entry, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks);

		if (Module->DllBase == (PVOID)hModule)
		{
			if (nSize * sizeof(WCHAR) < Module->FullDllName.Length)
			{
				SetLastErrorByStatus (STATUS_BUFFER_TOO_SMALL);
			}
			else
			{
				FileName.Length = 0;
				FileName.MaximumLength = nSize * sizeof(WCHAR);
				FileName.Buffer = lpFilename;

				RtlCopyUnicodeString (&FileName,
				                      &Module->FullDllName);
				Length = Module->FullDllName.Length / sizeof(WCHAR);
			}

			RtlLeaveCriticalSection (Peb->LoaderLock);
			return Length;
		}

		Entry = Entry->Flink;
	}

	SetLastErrorByStatus (STATUS_DLL_NOT_FOUND);
	RtlLeaveCriticalSection (Peb->LoaderLock);

	return 0;
}


/*
 * @implemented
 */
HMODULE
STDCALL
GetModuleHandleA ( LPCSTR lpModuleName )
{
	UNICODE_STRING UnicodeName;
	ANSI_STRING ModuleName;
	PVOID BaseAddress;
	NTSTATUS Status;

	if (lpModuleName == NULL)
		return ((HMODULE)NtCurrentPeb()->ImageBaseAddress);
	RtlInitAnsiString (&ModuleName,
	                   (LPSTR)lpModuleName);

	/* convert ansi (or oem) string to unicode */
	if (bIsFileApiAnsi)
		RtlAnsiStringToUnicodeString (&UnicodeName,
					      &ModuleName,
					      TRUE);
	else
		RtlOemStringToUnicodeString (&UnicodeName,
					     &ModuleName,
					     TRUE);

	Status = LdrGetDllHandle (0,
				  0,
				  &UnicodeName,
				  &BaseAddress);

	RtlFreeUnicodeString (&UnicodeName);

	if (!NT_SUCCESS(Status))
	{
		SetLastErrorByStatus (Status);
		return NULL;
	}

	return ((HMODULE)BaseAddress);
}


/*
 * @implemented
 */
HMODULE
STDCALL
GetModuleHandleW (LPCWSTR lpModuleName)
{
	UNICODE_STRING ModuleName;
	PVOID BaseAddress;
	NTSTATUS Status;

	if (lpModuleName == NULL)
		return ((HMODULE)NtCurrentPeb()->ImageBaseAddress);

	RtlInitUnicodeString (&ModuleName,
			      (LPWSTR)lpModuleName);

	Status = LdrGetDllHandle (0,
				  0,
				  &ModuleName,
				  &BaseAddress);
	if (!NT_SUCCESS(Status))
	{
		SetLastErrorByStatus (Status);
		return NULL;
	}

	return ((HMODULE)BaseAddress);
}


/*
 * @implemented
 */
BOOL
STDCALL
GetModuleHandleExW(IN DWORD dwFlags,
                   IN LPCWSTR lpModuleName  OPTIONAL,
                   OUT HMODULE* phModule)
{
    HMODULE hModule;
    NTSTATUS Status;
    BOOL Ret = FALSE;

    if (phModule == NULL ||
        ((dwFlags & (GET_MODULE_HANDLE_EX_FLAG_PIN | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT)) ==
         (GET_MODULE_HANDLE_EX_FLAG_PIN | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT)))
    {
        SetLastError(ERROR_INVALID_PARAMETER);
        return FALSE;
    }

    if (lpModuleName == NULL)
    {
        hModule = NtCurrentPeb()->ImageBaseAddress;
    }
    else
    {
        if (dwFlags & GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS)
        {
            hModule = (HMODULE)RtlPcToFileHeader((PVOID)lpModuleName,
                                                 (PVOID*)&hModule);
            if (hModule == NULL)
            {
                SetLastErrorByStatus(STATUS_DLL_NOT_FOUND);
            }
        }
        else
        {
            hModule = GetModuleHandleW(lpModuleName);
        }
    }

    if (hModule != NULL)
    {
        if (!(dwFlags & GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT))
        {
            Status = LdrAddRefDll((dwFlags & GET_MODULE_HANDLE_EX_FLAG_PIN) ? LDR_PIN_MODULE : 0,
                                  hModule);

            if (NT_SUCCESS(Status))
            {
                Ret = TRUE;
            }
            else
            {
                SetLastErrorByStatus(Status);
                hModule = NULL;
            }
        }
        else
            Ret = TRUE;
    }

    *phModule = hModule;
    return Ret;
}

/*
 * @implemented
 */
BOOL
STDCALL
GetModuleHandleExA(IN DWORD dwFlags,
                   IN LPCSTR lpModuleName  OPTIONAL,
                   OUT HMODULE* phModule)
{
    UNICODE_STRING UnicodeName;
    ANSI_STRING ModuleName;
    LPCWSTR lpModuleNameW;
    NTSTATUS Status;
    BOOL Ret;

    if (dwFlags & GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS)
    {
        lpModuleNameW = (LPCWSTR)lpModuleName;
    }
    else
    {
        RtlInitAnsiString(&ModuleName,
                          (LPSTR)lpModuleName);

        /* convert ansi (or oem) string to unicode */
        if (bIsFileApiAnsi)
            Status = RtlAnsiStringToUnicodeString(&UnicodeName,
                                                  &ModuleName,
                                                  TRUE);
        else
            Status = RtlOemStringToUnicodeString(&UnicodeName,
                                                 &ModuleName,
                                                 TRUE);

        if (!NT_SUCCESS(Status))
        {
            SetLastErrorByStatus(Status);
            return FALSE;
        }

        lpModuleNameW = UnicodeName.Buffer;
    }

    Ret = GetModuleHandleExW(dwFlags,
                             lpModuleNameW,
                             phModule);

    if (!(dwFlags & GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS))
    {
        RtlFreeUnicodeString(&UnicodeName);
    }

    return Ret;
}


/*
 * @implemented
 */
DWORD
STDCALL
LoadModule (
    LPCSTR  lpModuleName,
    LPVOID  lpParameterBlock
    )
{
  STARTUPINFOA StartupInfo;
  PROCESS_INFORMATION ProcessInformation;
  LOADPARMS32 *LoadParams;
  char FileName[MAX_PATH];
  char *CommandLine, *t;
  BYTE Length;

  LoadParams = (LOADPARMS32*)lpParameterBlock;
  if(!lpModuleName || !LoadParams || (((WORD*)LoadParams->lpCmdShow)[0] != 2))
  {
    /* windows doesn't check parameters, we do */
    SetLastError(ERROR_INVALID_PARAMETER);
    return 0;
  }

  if(!SearchPathA(NULL, lpModuleName, ".exe", MAX_PATH, FileName, NULL) &&
     !SearchPathA(NULL, lpModuleName, NULL, MAX_PATH, FileName, NULL))
  {
    return ERROR_FILE_NOT_FOUND;
  }

  Length = (BYTE)LoadParams->lpCmdLine[0];
  if(!(CommandLine = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
                               strlen(lpModuleName) + Length + 2)))
  {
    SetLastError(ERROR_NOT_ENOUGH_MEMORY);
    return 0;
  }

  /* Create command line string */
  strcpy(CommandLine, lpModuleName);
  t = CommandLine + strlen(CommandLine);
  *(t++) = ' ';
  memcpy(t, LoadParams->lpCmdLine + 1, Length);

  /* Build StartupInfo */
  RtlZeroMemory(&StartupInfo, sizeof(STARTUPINFOA));
  StartupInfo.cb = sizeof(STARTUPINFOA);
  StartupInfo.dwFlags = STARTF_USESHOWWINDOW;
  StartupInfo.wShowWindow = ((WORD*)LoadParams->lpCmdShow)[1];

  if(!CreateProcessA(FileName, CommandLine, NULL, NULL, FALSE, 0, LoadParams->lpEnvAddress,
                     NULL, &StartupInfo, &ProcessInformation))
  {
    DWORD Error;

    HeapFree(GetProcessHeap(), 0, CommandLine);
    /* return the right value */
    Error = GetLastError();
    switch(Error)
    {
      case ERROR_BAD_EXE_FORMAT:
      {
        return ERROR_BAD_FORMAT;
      }
      case ERROR_FILE_NOT_FOUND:
      case ERROR_PATH_NOT_FOUND:
      {
        return Error;
      }
    }
    return 0;
  }

  HeapFree(GetProcessHeap(), 0, CommandLine);

  /* Wait up to 15 seconds for the process to become idle */
  WaitForInputIdle(ProcessInformation.hProcess, 15000);

  CloseHandle(ProcessInformation.hThread);
  CloseHandle(ProcessInformation.hProcess);

  return 33;
}

/* EOF */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -