FORUM DARKERS

Administração => Darkers Project => Topic started by: Dark_Side on 09 de September , 2006, 05:41:54 AM

Title: [Source] Simples EXE Joiner em C
Post by: Dark_Side on 09 de September , 2006, 05:41:54 AM
Hi,
Segue abaixo um simples joiner que eu fiz em C.
Embora a lógica não seja a melhor, explicarei o funcionamento do programa.

 Quando simplesmente juntamos o conteúdo de dois arquivos, o arquivo resultante possui a soma de seus tamanhos, e apenas o primeiro é executado - como o Mago__ disse em outro post. Isso ocorre pois quando o programa é executado, depois que a entrada ExitProcess é localizada, o programa encerra.
 Este joiner é dividido em dois programas: o joiner propriamente dito, e o loader - responsável por executar os arquivos concatenados. O programa joiner, obtém dois arquivos, cria um cópia do loader e nesta cópia, insere o conteúdo dos dois arquivos abertos previamente. Após isso, o programa insere ainda, uma entrada com as posições read/write - posição de leitura/escrita - de cada arquivo: início e fim do arquivo 1; início e fim do arquivo 2.
 O loader (a cópia criada) por sua vez, obtém estas posições dentro do seu próprio código, as separa, e em seguida, lê o conteúdo da determinada faixa e o armazena no respectivo arquivo.

Exemplo:

Loader: XXX
Arquivo1: ABC
Arquivo1: 123

Após unir os arquivos, o loader ficaria assim:

XXXABC123
***3,6,9

A inicial *** serve apenas para identificar a string.
3 => onde começa o arquivo 1;
6 => onde termina o arquivo 1 e começa o arquivo 2 ;
9 => onde termina o arquivo 2.

Pois bem, segue agora o código:
joiner.c

#include <stdio.h>
#include <stdlib.h>

void erro(const char * erro){ // Função que notifica um erro e encerra
     puts(erro);
     system("pause");
     exit(1);
     }
int main()
{
FILE *arq1,*arq2,*loader; // Ponteiros para arquivos
char f1[0x100],f2[0x100]; //Buffers para os nomes dos arquivos
char * buffer1, * buffer2; //Buffers que irão armazenar o conteúdo dos arquivos
unsigned long int tam1,tam2,tam3; // Tamanho dos arquivos

    puts("**********************************************");
    puts("***    Simples EXE Joiner by Dark Side     ***");
    puts("**********************************************");
   
    puts(">> Caminho do arquivo 1:"); //Obtém e tenta abrir o primeiro arquivo
    fgets(f1,0x100,stdin); f1[strlen(f1)-1]='\0';
    if((arq1 = fopen(f1,"rb")) == 0) erro("Erro ao abrir o arquivo 1");
           
    puts(">> Caminho do arquivo 2"); //Obtém e tenta abrir o segundo arquivo
    fgets(f2,0x100,stdin); f2[strlen(f2)-1]='\0';
    if((arq2 = fopen(f2,"rb")) == 0) erro("Erro ao abrir o arquivo 2");


    system("copy loader.exe ARQUIVO_JOINED.exe"); // Faz cópia do loader
    if((loader = fopen("ARQUIVO_JOINED.exe","r+b")) == 0)  erro("Erro ao abrir o loader");

   fseek(arq1,0,SEEK_END); // Posiciona read/write no fim
   fseek(arq2,0,SEEK_END);
 
  //Obtém seus tamanhos
   tam1 = ftell(arq1);
   tam2 = ftell(arq2);

if(tam1 == 0 || tam2 == 0) erro("Um dos arquivos esta vazio");
   
   // Aloca espaço nos buffers     
   buffer1 = (char*)malloc(tam1+1);
   buffer2 = (char*)malloc(tam2+1);
if(buffer1 == NULL || buffer2 == NULL) erro("Erro ao alocar espaco no buffer");
                   
   //Retorna os arquivos ao início e os lê.               
   rewind(arq1);
   rewind(arq2);
   fread(buffer1,tam1,1,arq1);
   fread(buffer2,tam2,1,arq2);

   
   fseek(loader,0,SEEK_END); //Posiciona read/write do loader no fim
   tam3 = ftell(loader); // Obtém tamanho do loader
   
   // Lê os arquivos
   fwrite(buffer1,1,tam1,loader); // Escreve o primeiro arquivo no loader
   fwrite(buffer2,1,tam2,loader); // Escreve o segundo arquivo no loader
   
   /* Abaixo o programa irá escrever as respectivas posições de leitura/escrita de cada arquivo
      O formato seria: ***X,Y,Z
      X = fim do loader e início do arquivo 1; Y = Início do arquivo 2; Z = fim do arquivo 2
   */
   fprintf(loader,"***%lu,%lu,%lu",tam3,tam1+tam3,tam1+tam2+tam3);

   //Fecha os arquivos
   fclose(arq1);
   fclose(arq2);
   fclose(loader);

   // Libera o espaço alocado nos buffers.
   free(buffer1);
   free(buffer2);
   puts("Arquivos conatenados em ARQUIVO_JOINED.EXE");
   system("pause");
return 0;
}

loader.c
#include <stdio.h>
#include <stdlib.h>

int main(int num,char ** arg)
{
    FILE *fp = fopen(arg[0],"rb"); // Abre a cópia do loader
    if(fp == 0) return 0;
    //Ponteiro para os dois arquivos unidos
    FILE *arq1=fopen("arq1.exe","wb"),*arq2=fopen("arq2.exe","wb");
    unsigned int tam; //Tamanho do arquivo loader
    char * buffer; //Buffer que irá armazenar o conteúdo
   
    fseek(fp,0,SEEK_END); // Move a posição read/write para o fim
    tam = ftell(fp); //Obtém tamanho do arquivo
    buffer = (char*)malloc(tam+1); // Aloca espaço
rewind(fp); // Retorna a read/write para zero
fread(buffer,tam,1,fp); // Lê o arquivo
int i;
for(i=0;i<tam;i++)
if(buffer[i]=='*' && buffer[i+1]=='*'  && buffer[i+2]=='*') { //Tenta encontrar "***" no buffer
fseek(fp,i,SEEK_SET); // Se encontrar, move a posição read/write para a posição onde a string está.
goto continua; // Pula para o label "continuar";
break; // Para o loop
}
// Caso não tenha encontrado a string:

    // Fecha arquivos
    fclose(fp);
    fclose(arq1);
    fclose(arq2);

    free(buffer); //Libera espaço alocado
return 0; // Encerra

continua:
memset(buffer,0,tam); // Limpa todo o buffer
fread(buffer,0x30,1,fp); // Lê 50 bytes a partir da posição da string ("***"), o que deve ser suficiente.
unsigned long seek1,seek2,seek3; // Posições read/write
seek1 = atol(strtok(buffer,"*,")); // Obtém a posição read/write inicial do arquivo 1
seek2 = atol(strtok(NULL,",")); // Obtém posição inicial do arquivo 2
seek3 = atol(strtok(NULL,",")); // Obtém posição final do arquivo 2

fseek(fp,seek1,SEEK_SET); // Posição do arquivo 1
memset(buffer,0,seek2-seek1); // Reserva espaço
fread(buffer,seek2-seek1,1,fp); // Lê dados
fwrite(buffer,seek2-seek1,1,arq1); // Escreve no arquivo 1

fseek(fp,seek2,SEEK_SET); // Posição do arquivo 2
memset(buffer,0,seek3-seek2); // Reserva espaço
fread(buffer,seek3-seek2,1,fp); // Lê dados
fwrite(buffer,seek3-seek2,1,arq2); // Escreve no arquivo 2


    // Fecha arquivos
    fclose(fp);
    fclose(arq1);
    fclose(arq2);

    free(buffer); //Libera espaço alocado

   //Executa os arquivos
   system("start arq1.exe");
   system("start arq2.exe");

    return 0;
   
}

Bem é isso,
Carry on...
Bye.
Title: Re: [Source] Simples EXE Joiner em C
Post by: Anonymous on 09 de September , 2006, 12:21:01 PM
Excelente Dark_Side. eu nunca tinha conseguido encontrar um código de joiner... mentira, encontrei 1 uma vez mas nem lembro onde...

Bem, minha dúvida está respondida em termos... eu queria fazer o Joiner de uma outra forma (a forma que postei no meu post, fazendo com que não fosse escrito o exitproccess do primeiro nem o cabeçalho do segundo).

Se souber como, me ajude aí viu?

Abraços
Title: Re: [Source] Simples EXE Joiner em C
Post by: anakim on 09 de September , 2006, 01:27:44 PM
Bom Post, + tipo aconselho pra quem usa joiners pra juntar imagens a seus proprios programas criados por vc, use a tecnica Picture-Runtime que ocupa menos tamanho e mais inteligente abaixo o link:

www.darkers.com.br/smf/index.php/topic,1745.0.html (//http://www.darkers.com.br/smf/index.php/topic,1745.0.html)
Title: Re: [Source] Simples EXE Joiner em C
Post by: insanity on 09 de September , 2006, 06:42:02 PM
Boa dark side, deu para entender a logica de seu programa ;)


ate mais