Desembalar um executável a partir de dentro de uma biblioteca em C / C ++
-
20-08-2019 - |
Pergunta
Estou desenvolvendo uma biblioteca que usa um ou mais executável helper no curso de fazer negócios. Minha implementação atual requer que o usuário tenha o executável ajudante instalado no sistema em um local conhecido. Para a biblioteca para funcionar corretamente o aplicativo auxiliar deve estar no local correto e ser a versão correta.
gostaria de removido o requisito de que o sistema seja configurado no modo acima.
Existe uma maneira de agrupar o executável auxiliar na biblioteca tal que possa ser desembalado em tempo de execução, instalado em um diretório temporário, e usado para a duração de um prazo? No final da corrida o executável temporário pode ser removido.
Eu tenho considerado gerar automaticamente um arquivo que contém uma matriz de char não assinado que contém o texto do executável. Isso seria feito em tempo de compilação como parte do processo de construção. Em tempo de execução esta string seriam gravados em um arquivo criando assim o executável.
Seria possível fazer tal tarefa sem escrever o executável para um disco (talvez algum tipo de disco RAM)? Eu poderia imaginar determinados scanners de vírus e outra objeção software de segurança para tal operação. Existem outras preocupações que eu deveria estar preocupado?
A biblioteca está sendo desenvolvido em C / C ++ para uso de plataforma cruzada no Windows e Linux.
Solução
Você pode usar xxd
para converter um arquivo binário para um arquivo de cabeçalho C.
$ echo -en "\001\002\005" > x.binary
$ xxd -i x.binary
unsigned char x_binary[] = {
0x01, 0x02, 0x05
};
unsigned int x_binary_len = 3;
xxd
é bastante normal em sistemas * nix, e está disponível no Windows com Cygwin ou MinGW ou Vim inclui-lo no instalador padrão também. Este é um cross-platform maneira extremamente para incluir dados binário em código compilado.
Outra abordagem é usar objcopy
para acrescentar dados para o final de um arquivo executável - IIRC você obter objcopy
e usá-lo para PEs no Windows.
Uma abordagem que eu como um pouco melhor do que isso é apenas dados de acréscimo matérias direto para a final do seu arquivo executável. No executável, você procura para o final do arquivo, e ler em um número, indicando o tamanho dos dados de binário anexado. Então você procurar para trás que muitos bytes, e fread
que os dados e copiá-lo para o sistema de arquivos, onde você poderia tratá-lo como um arquivo executável. Este, aliás, é a maneira que muitos, se não tudo, executáveis ??auto-extraíveis são criados .
Se você acrescentar os dados binários, ele trabalha com ambos os arquivos do Windows PE e arquivos * nix ELF - nenhum deles ler além do "limite" do executável
.Claro que, se você precisa anexar vários arquivos, você pode anexar um tar / zip arquivo em seu exe, ou você vai precisar de uma estrutura um pouco mais dados antecedência para ler o que está anexado.
Você também provavelmente vai querer UPX seus executáveis ??antes de anexá-las.
Você pode também estar interessado no LZO biblioteca , que é declaradamente um das bibliotecas de compressão mais rápido-descompressão. Eles têm uma biblioteca MiniLZO que você pode usar para um descompressor muito leve. No entanto, as bibliotecas LZO é licenciado sob a GPL, de modo que força significa que você não pode incluí-lo em seu código-fonte a menos que seu código é GPL também. Por outro lado, existem licenças comerciais disponíveis.
Outras dicas
"Uma pessoa inteligente resolve um problema. A quem é sábio evita-lo." - Albert Einstein
No espírito desta citação, eu recomendo que você simplesmente agrupar este executável junto com a aplicação final.
Apenas meus 2 centavos.
abordagem um pouco diferente do que usando um unsigned char * array é colocar todo o binário executável como recurso da dll. Em tempo de execução, você pode salvar os dados binários como um arquivo temporário local e executar o aplicativo. Eu não tenho certeza se há uma maneira de executar um executável na memória, apesar de tudo.
Para a biblioteca para funcionar corretamente o aplicativo auxiliar deve estar na correta localização
No Windows, isso seria o diretório Arquivos de Programas ou diretório System32?
Isso pode ser um problema. Quando um aplicativo é instalado, particularmente em um ambiente corporativo, que normalmente acontece em um contexto com direitos administrativos. No Vista e mais tarde com o UAC ativado (o padrão), isso é necessário para escrever a determinados diretórios. E a maioria dos sabores de Unix tiveram restrições sensatas como que por tanto tempo quanto qualquer um pode lembrar.
Então, se você tentar fazê-lo no momento em que as chamadas aplicativo host em sua biblioteca, que podem não ser em um contexto com direitos suficientes para instalar os arquivos, e assim sua biblioteca iria colocar restrições sobre a aplicação host.
(Outra coisa que vai ser descartada é alterações no registro, ou atualizações do arquivo de configuração sobre os vários Unices, se o aplicativo host não tem a capacidade de elevar o processo a um nível administrativo.)
Dito tudo isso, você diz que está considerando desembalar os ajudantes em um diretório temporário, então talvez tudo isso é discutível.
Qt tem um excelente método de alcançar este: QResource
"O sistema de recursos Qt é um mecanismo independente de plataforma para armazenar arquivos binários no aplicativo executável."
Você não diz se você está usando Qt, mas você dizer "C ++ para uso de plataforma cruzada no Windows e Linux", assim mesmo se você não estiver usando, você pode querer considerar começar.
Há uma maneira no Windows para executar um executável de dentro memória sem escrevê-lo em disco. O problema é que, devido aos sistemas de segurança modernos (DEP) isso provavelmente não irá funcionar em todos os sistemas e quase qualquer scanner anti-malware vai detectá-lo e avisar o usuário.
Meu conselho é simplesmente empacotar o executável em sua distribuição, é certamente a maneira mais confiável para alcançar este objectivo.
Bem, o meu primeiro pensamento seria: o que faz este ajudante executável fazer isso não poderia ser feito dentro do próprio código da sua biblioteca, talvez usando um thread secundário, se necessário. Isso pode ser algo a considerar.
Mas, como para a questão real ... Se a sua "biblioteca" é realmente empacotados como uma dll (ou mesmo um exe), então pelo menos o Windows tem suporte relativamente simpe para a incorporação de arquivos dentro de sua biblioteca.
O mecanismo de recurso que permite coisas como informações sobre a versão e ícones para ser incorporado dentro executáveis ??também pode permitir que pedaços arbitrários de dados. Desde que eu não sei o ambiente de desenvolvimento que você está usando, eu não posso dizer exatamente como fazer isso. Mas a grosso modo, você precisa criar um recurso personalizado com um tipo de "FILE" ou algo sensível como essa e apontá-lo para o exe que você deseja incorporar.
Então, quando você quer para extraí-lo, você iria escrever algo como
HRSRC hResource = FindResource(NULL, MAKEINTRESOURCE(IDR_MY_EMBEDDED_FILE), "FILE");
HGLOBAL hResourceData = LoadResource(NULL, hResource);
LPVOID pData = LockResource(hResourceData);
HANDLE hFile = CreateFile("DestinationPath\\Helper.exe", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
DWORD dwBytesWritten = 0;
WriteFile(hFile, pData, SizeofResource(NULL, hResource), &dwBytesWritten, NULL);
CloseHandle(hFile);
(preenchendo seu próprio caminho desejado, nome do arquivo, e qualquer erro apropriada verificação é claro)
Depois disso, o exe ajudante existe como um arquivo exe normal e para que você possa executá-lo, contudo, você normalmente faria.
Para remover o arquivo após o uso, você deve investigar as bandeiras para CreateFile
, particularmente FILE_FLAG_DELETE_ON_CLOSE
. Você também pode olhar para usando MoveFileEx
quando se combina a bandeira MOVEFILE_DELAY_UNTIL_REBOOT
com NULL passado para o novo nome de arquivo. E, claro, você sempre pode excluí-lo em seu próprio código, se você pode dizer quando o executável foi encerrada.
Eu não sei o suficiente sobre executáveis ??do Linux, então eu não sei se um recurso semelhante está disponível lá.
Se o Linux não fornece qualquer mecanismo conveniente e / ou se essa ideia não atender às suas necessidades no Windows, então eu suponho que a sua ideia de gerar uma matriz de char não assinado do conteúdo do exe ajudante seria a próxima melhor maneira de incorporar o exe em sua biblioteca.