Menu

Mostrar postagens

Esta seção permite que você visualize todas as postagens feitas por este membro. Observe que você só pode ver postagens feitas em áreas às quais tem acesso atualmente.

Menu Mostrar postagens

Mensagens - kuroi

#256
Bom dia, cara!

Sim. No caso do Dumper, você deve abrir o arquivo em modo Binário utilizando-se dos parâmetros "rb" dentro da função fopen() para que o compilador entenda que o arquivo que está sendo lido ("r" de read) está em modo binário ("b" de binary).
Mas como obviamente estamos trabalhando com dois arquivos (ainda no caso do Dumper), temos também que declarar um segundo arquivo que deverá ser aberto em modo texto para que nele seja armazenado o resultado do Dumper. Porém, em C, quando realizamos a abertura de um arquivo em modo texto, não é necessário especificar o parâmetro "wt" (write text), pois por padrão a linguagem já determina que qualquer abertura de arquivo está em modo texto. Assim sendo, a abertura do arquivo de texto só carrega o parâmetro "w" (write).

Exemplos:

FILE *arquivo_dump;
FILE *arquivo_saida;


     arquivo_dump = fopen("Binário_orig.bin", "rb");

     arquivo_saida = fopen("Dump.txt", "w");

Agora, no caso do Inserter, temos que nos atentar para algumas coisas antes
declarar a abertura dos arquivos...

Na prática, o Dumper é o programa que lerá o arquivo binário e gravará só seu conteúdo textual dentro de um txt. E o Inserter é o programa que lerá arquivo txt e gravará todo seu conteúdo no arquivo binário.
Tendo isso em mente, sabemos que ao declarar a abertura dos arquivos no Inserter, temos que abrí-los da seguinte forma:

FILE *entrada_txt, *saida_bin;

     entrada_txt = fopen("Script.txt", "r");

     saida_bin = fopen("rom.bin", "r+b");

Repare que na abertura do arquivo de entrada é especificado só o "r" no segundo parâmetro da função fopen, mostrando que trata-se de uma leitura de um arquivo no modo texto.
Já o arquivo binário recebe o prefixo "r+b" dentro do segundo parâmetro,
mostrando que este arquivo será aberto para "leitura E escrita" em modo
binário.
Mas como são só dois tipos principais de dados que podem ser lidos ou
gravados em tratamento de arquivos em C (Texto ou Binário), o resto é só
entender como funcionam os parâmetros da função fopen().

Vou deixar aqui o código da minha função Dumper com cada linha comentada para ficar mais didático o seu entendimento.

void Dumper(char* nome, unsigned int OffsetInicioTexto, unsigned int OffsetFinalTexto){
    FILE *arquivo;
    FILE *arquivo_saida;
    unsigned char *memoria;
    int cont = 0;
    int l;
    unsigned int k=0;
    unsigned int n=0;
    unsigned int OffsetInicioPonteiros;
    unsigned int OffsetFinalPonteiros;
    unsigned int h;
    unsigned int i, j;

    unsigned char tabela[256] = "ABCDEFGHIJKLMNOP"
    "QRSTUVWXYZabcdef"
    "ghijklmnopqrstuv"
    "wxyz0123456789ÂÃ"
    "ÄÇÈÉÊËÎÏÔÖÛÜ-ÓÙÚ"
    "àáâãçèé%úêõîïôíñ"
    "óöûü@.,!?;: @@@'"
    "@@@@@@$@@@@@@@@@"
"@@@@@@@@@@@@@@@@"
"@@@@@@@@@@@@@@@@"
"@@@@@@@@@@@@@@@@"
"@@@@@@@@@@@@@@@@"
"@@@@@@@@@@@@@@@@"
"@@@@@@@@@@@@@@@@"
"@@@@@@@@@@@@@@@@"
"@@@@@@@@@@@@@@@*";
   
   
        //Abre o arquivo de leitura   
        arquivo = fopen("Crystalis (U) [C][!].gbc", "rb");
       
        //Inicia o ponteiro do arquivo no começo
        fseek (arquivo, OFFSET, SEEK_SET);
       
        //Aloca em memória um unsigned char de tamanho 2097152 em decimal
        memoria = (unsigned char*) malloc (sizeof(unsigned char)*TAM_ARQ);
       
        //Lê o arquivo de entrada e grava todos os seus bytes na memória, retornando um contador, ou seja, dando um Malloc na bagaça
        cont = fread (memoria, sizeof(unsigned char), TAM_ARQ, arquivo);
       
       
        //Depois que toda a rom estiver na memoria, o arquivo é fechado
        fclose(arquivo);
       
        //Abre o arquivo de saída
        arquivo_saida = fopen(nome, "wt");

   
            //Inicio do loop que irá percorrer todo o bloco de diálogos a fim de gravar seus dados no arquivo de saída
            for(i=OffsetInicioTexto;i<=OffsetFinalTexto;i++){

   
   
            //Verificação se houve uma quebra de linha
            if(memoria[i] == 0xf1){
            //Gravação do dado hexadecimal F1 dentro de parênteses no arquivo de saída
            fprintf(arquivo_saida, "{%.2x}\n", memoria[i]);
}

//Verificação se houve um fim de diálogo
else if(memoria[i] == 0xf8){
//Gravação do dado hexadecimal F8 dentro de parênteses no arquivo de saída
fprintf(arquivo_saida, "{%.2x}\n------------------\n", memoria[i]);
}


//Se não houver mais nenhum caractere de controle, inserir o caractere coincidindo-o com a tabela de caracteres previamente criada
else{
//Se o caractere lido for igual a @
if(tabela[memoria[i]] != '@'){

//O programa grava o caractere no arquivo de saída coincidindo-o com o valor na tabela
fprintf(arquivo_saida, "%c", tabela[memoria[i]]);
}
               
            }



            }
       
            //Fechamento do arquivo de saída
            fclose(arquivo_saida);
           
           
            //Liberação da memória utilizada
            free(memoria);           
           
           
           
           
           
}



Obs: Ondinha, eu fui procurar saber como poderia desenvolver esse módulo em C
para tratar dos arquivos .tbl que você comentou, e vi que isso na verdade se
trata daquelas famosas "Listas Encadeadas por Ponteiros", né? Se for o mesmo
assunto (que exige um type def struct e tudo mais...) eu ainda não vejo como
poderia implementar isso em um gerenciador de arquivos .tbl... Vou começar a
estudar sobre isso e aí passo aqui no fórum pra comentar...


Até mais!!
#257
Dúvidas e Ajuda / Ajuda com ASM Hacking de Ponteiros
Março 16, 2017, 18:46:25 PM
Boa noite, senhores!
Aqui estou eu de volta com mais algumas dúvidas sobre a minha caminhada incessante no intuito de se tornar um Romhacker!

Atualmente estou pegando pesado nos estudos do meu Dumper/Inserter em C para o jogo do Crystalis de GBC.

Até então, com meu próprio esforço eu consegui fazer um software totalmente funcional (console) que retira os textos da ROM, reinsere os mesmos (comparando o número de caracteres entre o Script original e o modificado) e também calcula os ponteiros. Ou seja, a ferramenta já está deveras completa...

Porém, me surgiu um pequeno problema, que até tinha comentado no chat. Ao reescrever os Scripts na ROM, os endereços dos ponteiros originais são, algumas vezes "atropelados", pelo Script modificado. Mesmo depois de modificar os ponteiros para o próximo diálogo. Ou seja, existe sempre algo dizendo que a tabela de ponteiros deve iniciar e terminar sempre no mesmo intervalo de Offsets...

Frente a isso, parti para estudos em ASM para Gameboy. Achei vários sites interessantes sobre ASM Hacking de Gameboy, porém ainda não consigo fazer muita coisa dentro do debugger gbp...

Eu gostaria de alguma luz de alguém aqui do fórum que possa me indicar alguma forma de encontrar os endereços desses Ponteiros dentro da ROM...

Obrigado e até mais!!
#258
Bom dia, cara.

Não sei se isso pode te ajudar em seus estudos, mas quando eu estava estudando pra criar o meu próprio Dumper/Inserter do jogo Crystalis de GBC, eu também me deparei com um problema semelhante ao seu.
A Rom na qual eu estava trabalhando não possuía nenhuma compressão gráfica e nem tão pouco textual, porém havia um pequeno problema na hora de extrair os textos: O jogo não se utilizava da tabela de caracteres ASCII, padronizada para o mercado americano...

Ora, mas se eu utilizasse um editor hexadecimal comum, com certeza eu teria sucesso em recriar a sua tabela fazendo uma busca relativa na rom, certo? Certo. Porém esse não era o meu objetivo. Na verdade eu queria desenvolver um Algoritmo que fosse capaz de transcodificar o conteúdo textual do jogo que estava na tabela "X" para a tabela ANSI (para que pudesse visualizar também caracteres acentuados).

Com a ajuda de um Software de busca relativa (Monkey Moore, o melhor que já usei!), eu consegui descobrir algum conteúdo de dentro da rom e com isso cheguei à seguinte tabela:

A=00
B=01
C=02
D=03
...
e etc.

Obs: Os valores estão em hexadecimal.

Já a famosa tabela ASCII possui os seguintes valores:

A=41
B=42
C=43
D=44
...
e etc.


Certo. Agora, se eu conseguisse carregar a tabela do jogo Crystalis no meu Editor Hexadecimal obviamente eu teria todos os caracteres da rom visíveis para edição. Mas como eu já havia mencionado, este não era o meu objetivo.

Em busca de algum Algoritmo que pudesse me ajudar a Dumpar textos de uma rom, eu encontrei lá no Po.BR.e o Script do Hyllian, que traduziu o Castlevania Order of Eclesia do Nintendo DS

http://romhackers.org/modules/PDdownloads2/singlefile.php?cid=9&lid=236

Como o seu código estava em C (linguagem que eu relativamente conheço), ficou mais fácil de entender a lógica que ele utilizou para que o seu código Dumper pudesse trabalhar com uma tabela não padronizada.

O script do Hillian foi o seguinte (nota: Vou utilizar a tabela que eu criei no Crystalis como exemplo):

   //primeiro há a declaração de um Array de caracteres logo no início do programa

       unsigned char tabela[256] = "ABCDEFGHIJKLMNOP"
                    "QRSTUVWXYZabcdef"
                    "ghijklmnopqrstuv"         
                    "wxyz0123456789ÂÃ"
                    "ÄÇÈÉÊËÎÏÔÖÛÜ-ÓÙÚ"         
                    "àáâãçèé%úêõîïôíñ"         
                    "óöûü@.,!?;: @@@'"         
                    "@@@@@@$@@@@@@@@@"         
                "@@@@@@@@@@@@@@@@"         
                "@@@@@@@@@@@@@@@@"         
                "@@@@@@@@@@@@@@@@"         
                "@@@@@@@@@@@@@@@@"
                "@@@@@@@@@@@@@@@@"
                "@@@@@@@@@@@@@@@@"
                "@@@@@@@@@@@@@@@@"
                "@@@@@@@@@@@@@@@*";
      

O Array acima possui 256 posições. Aí você me pergunta "Por que tudo isso?" Ora, simplesmente porque como queremos converter todas as 256 posições da tabela do jogo para uma tabela proveniente da tabela ASCII , temos que fazer comparações com dois Arrays identicos em tamanho, caso contrário iríamos nos deparar com problemas de "Array Out of Bounds".

Com relação à posição dos caracteres, repare que na minha tabela, os primeiros caracteres já são "A,B,C,D... e etc..."
Isso se dá pelo fato de que o compilador entenderá que a posição 0x00 do vetor "tabela" é igual a A, a posição 0x01 do vetor "tabela" é igual a B e assim sucessivamente até que a tabela atinja 256 (de 0 a 255) caracteres ou 0xFF.

Assim sendo, o código do Hyllian continua executando as rotinas que ele mesmo arquitetou até que chegamos às seguintes linhas:

if(tabela[memoria] != '@'){

          fprintf(arquivo_saida, "%c", tabela[memoria]);
}

O código acima verifica primeiro se o caractere que foi lido binariamente pelo programa, tem um correspondente em minha tabela, além de verificar se ele é diferente de @. Se essa afirmação for falsa, o programa não irá gravar nada no arquivo de saída, pois o caractere @ só serve para preencher espaços não utilizados na tabela.
Porém, se a afirmação for verdadeira, quer dizer que o caractere lido binariamente possui sim um correspondente em minha tabela.
Agora só falta gravar o valor correspondente deste caractere em meu arquivo de saída (o Dump). Ou seja, é isso que a próxima linha de instrução representa: A gravação do valor encontrado, correspondente à minha tabela. Ou melhor dizendo, o caractere já tratado e convertido para ANSI.

Espero ter ajudado e qualquer dúvida estamos aí!

Até mais!!
#259
Dúvidas e Ajuda / Re:[PS2] Ajuda nos ponteiros.
Dezembro 17, 2016, 14:49:45 PM
Wow! E não é que o grande Rafael Quinalha ataca novamente!
Pois é, daquela vez eu apanhei pra caramba pra criar essa tool e acabei ficando sem tempo pra fazer alguma coisa... O nosso amigo Unknown Master até que se prontificou a ajudar, mas também acabou ficando sem tempo por conta da sua faculdade...

E que notícia boa, rapaz! Então vai ser uma menina? O meu garotão já vai fazer dois anos em Março!

E sobre os Scripts, eu já tenho tudo traduzido e só falta reinserirmos na ISO.

Até mais!!
#260
Geral / Re:Finalmente o fórum está de volta
Outubro 30, 2016, 20:58:38 PM
Wow!! Finalmente o Fórum voltou!
Me pegaram de surpresa! Valeu gente!!