Pergunta

Um módulo pode ser descarregado, então como posso dizer com certeza se ainda está na memória? Eu tenho uma alça, obtida do getModuleHandle. Quando tentei chamar GethandleInformation, vejo o erro 0xc0000008 - "Foi especificado um identificador inválido". Isso aconteceu antes que pudesse ser descarregado.

Foi útil?

Solução

O termo "identificador" está um pouco sobrecarregado aqui - muitas classes diferentes de objetos na API Win32 são chamadas de "alças".

Gethandleinformation é usado para alças para objetos de kernel - arquivos, chaves de registro, mutexes, etc.

O hmodule retornado pelo getModuleHandle é usado pelo carregador e não é um objeto de kernel real; portanto, a informação do GethandleinMa falha. Nenhuma das bandeiras que você obtém em Gethandleinformation faz sentido para o hmodule.

Se você deseja verificar se o hmodule ainda está carregado na memória, basta ligar para o getModuleHandle - essa API deve ser rápida o suficiente para ligar muitas vezes. No entanto, o resultado do getModuleHandle pode ser inválido no momento em que retorna - outro thread poderia ter chamado de freelibrary. É melhor garantir que a DLL permaneça carregada. Você pode fazer isso chamando você mesmo ou chamando getModuleHandleEx, o que aumentará a contagem de referência da DLL.

Outras dicas

Duas soluções:

1

Ligue para getModuleFileName () no hmodule. Se o módulo estiver carregado, você receberá um nome de arquivo válido. Se não estiver carregado, você não receberá um nome de arquivo válido. Certifique -se de definir o primeiro byte da matriz de nome de arquivo devolvida como ' 0' antes de ligar para getModuleFileName () ou para verificar o valor de retorno. Se você definir o primeiro byte antes da chamada, poderá efetivamente ignorar o valor de retorno e apenas tratar a sequência de comprimento zero como um sinal "não carregado".

TCHAR szModName[MAX_PATH + 1];

szModName[0] = _T('\0');
GetModuleFileName(hMod, szModName, MAX_PATH);

// zero length string if not loaded, valid DLL name if still loaded

2

Chame VirtualQuery () Passando o Hmodule como o endereço para a consulta. Como um experimento, faça isso em uma biblioteca carregada e em uma biblioteca, você sabe ser libertado. Você descobrirá que eles têm resultados muito diferentes para a memória retornada_basic_information. Deixo para você elaborar um algoritmo adequado para determinar a diferença entre os dois.

Embargo

Obviamente, a ressalva que outro thread pode descarregar a biblioteca enquanto você está executando o EIHER desses testes se aplica. Na minha experiência, é muito improvável que isso aconteça, mas isso depende muito do que você está fazendo, por que está fazendo isso e quando está fazendo isso no caminho de execução do programa. Use com cuidado.

É uma API muito simples.

PIMAGE_NT_HEADERS (NTAPI* _RtlImageNtHeader)

Programa de amostra:

(PVOID)typedef PIMAGE_NT_HEADERS (NTAPI *RTLIMAGENTHEADER)(PVOID);
RTLIMAGENTHEADER RtlImageNtHeader;
HMODULE hDll = GetModuleHandle("ntdll.dll");
HMODULE hDllTmp = LoadLibrary("ws2_32.dll");
RtlImageNtHeader = (RTLIMAGENTHEADER)GetProcAddress(hDll,"RtlImageNtHeader");

struct _IMAGE_NT_HEADERS *r,*r2;
r= RtlImageNtHeader(hDllTmp); 
FreeLibrary(hDllTmp);
r2= RtlImageNtHeader(hDllTmp);

//r = NULL
//r2 = return ws2_32 PE Header address
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top