Fórum Unificado de Romhacking e Tradução

Romhacking e Tradução de Jogos => Dúvidas e Ajuda => Tópico iniciado por: Snow online Outubro 02, 2018, 11:29:51 AM

Título: Possibilidade de "find and replace" uma lista de hexadecimais
Enviado por: Snow online Outubro 02, 2018, 11:29:51 AM
Olá pessoal, estou precisando de ajuda com uma situação que me apareceu durante minha caminhada, procurei e testei vários editores hexadecimais, mas não consegui algo que realizasse o seguinte:
-Tenho vários Hexadecimais originais fora de sequência.
ex:
Lista original, na ROM:

WWWWWWWW B1B2B3B4 C1C2C3C4 D1D2D3D4
E1A2A3A4 F1B2B3B4 XXXXXXXX YYYYYYYY
A1A2A3A4 ZZZZZZZZ C1C2C3C4 D1D2D3D4

Obs: o tamanho é o mesmo para cada um dos que serão substituídos.

Quero substituir os que estão em negrito por uma outra sequência de Hexadecimais, fincando por exemplo:
AAAAAAAA B1B2B3B4 C1C2C3C4 D1D2D3D4
E1A2A3A4 F1B2B3B4 CCCCCCCC FFFFFFFF
A1A2A3A4 CCCCCCCCC1C2C3C4 D1D2D3D4

Estou fazendo manualmente, pois os editores que testei, substitui uma única sequência por vez.
O que preciso é: um editor que pegue a lista a procurar e substitua pela outra lista.
Procurar por:
WWWWWWWW
XXXXXXXX
YYYYYYYY
ZZZZZZZZ
Substituir em sequência por:
AAAAAAAA
CCCCCCCC
FFFFFFFF
CCCCCCCC

Se alguém conhecer algum programa que faça essa tarefa, ou alguma maneira de se conseguir isso.
Título: Re:Possibilidade de "find and replace" uma lista de hexadecimais
Enviado por: denim online Outubro 02, 2018, 12:08:19 PM
Eu não conheço, e acho difícil encontrar um programa que faça algo tão específico...
Título: Re:Possibilidade de "find and replace" uma lista de hexadecimais
Enviado por: Snow online Outubro 02, 2018, 15:09:22 PM
Então denim... eu imaginei que pudesse ter, por que nada mais é do que ao invés de procurar e substituir por um valor.... seria uma cadeia de valores... Sou leigo em programação, to estudando o código C de um programa de Inserção e recalculo de ponteiros para ver se consigo adaptar...
Título: Re:Possibilidade de "find and replace" uma lista de hexadecimais
Enviado por: tvtoon online Outubro 02, 2018, 16:37:29 PM
Existem várias considerações sobre o assunto...

1) É uma lista fixa de valores repetidos assim, em larga escala?

2) Você sabe o escopo desses valores a serem substituídos? O objetivo é saber se há uma repetição após esse trecho lógico a ser substituído.

3) Você tem certeza que essa lista não pode ser obtida na imagem binária, via ponteiros no mínimo?

4) Finalmente, qüal a finalidade dessa substituição? Textos, gráficos etc...
Título: Re:Possibilidade de "find and replace" uma lista de hexadecimais
Enviado por: Kamppello online Outubro 02, 2018, 16:46:51 PM
Se não me engano o Hex Editor Neo faz isso, entretanto ele não carrega tabelas.
Título: Re:Possibilidade de "find and replace" uma lista de hexadecimais
Enviado por: Snow online Outubro 03, 2018, 00:41:59 AM
tvtoon, considerações importantes as suas:

1) Os valores são ponteiros originais, quero substituir por ponteiros modificados.

2) Os ponteiros não estão todos em sequência, não consigo usar o Kruptar por exemplo, estudei muito ele, mas quando vai para o ponteiro que está fora de ordem, acaba dando problema.

3) Eles são os ponteiros, consegui de uma forma alternativa alterá-los automaticamente usando um Dump de texto pra marcar os offsets dos finais de cena e importando pro Excel. Maneira meio que alternativa, mas é com o que sei trabalhar.... então com alguns cliques consigo pegar os ponteiros originais numa coluna e na seguinte tenho eles recalculados.

4) Substituição de ponteiros antigos, por novos. Esses ponteiros não seguem uma sequência no bloco.

Então a ideia era com Editor Hex fazer a substituição no arquivo do jogo.

Buscar: pont1, pont2, pont3, pont4 (a lista q tenho de valores hexadecimais distintos na coluna do excel)
Subistituir por: pont1_recalculado, pont2_recalculado, pont3_recalculado...

acabei de fazer 80!!! um por um!

Kamppelo,
Com certeza irei testá-lo agora.
Título: Re:Possibilidade de "find and replace" uma lista de hexadecimais
Enviado por: kuroi online Outubro 03, 2018, 07:22:45 AM
Bom dia, cara!
Então... Quando me deparei com esse tipo de problema, eu fui "obrigado" a inserir no arquivo de Dump os valores encontrados referentes aos endereços dos ponteiros originais no cabeçalho de cada script dumpado. Por exemplo:

{000A35D8}
O homem veio da galinha,{0A}
mas a galinha nega{0A}
paternidade.{00}

Depois, na hora de reinserir você obtem o valor do ponteiro novo baseado na posição atual que você estiver no arquivo binário de saída, alocando-o em uma variável chamada "ponteiro_novo" e captura o endereço do ponteiro original (que está impresso no Dump) em uma variável chamada "ponteiro_orig".

Com os dois em mãos, crie uma função (ou método, dependendo da linguagem) que faz o cálculo do ponteiro passando por parâmetro o ponteiro_orig e o ponteiro_novo. Aí dentro da função você grava o ponteiro_novo na posição em que estava o ponteiro_orig.

Simples assim! Rsrsrs

Se tiver mais dúvidas, eu irei procurar o código que eu tenho em C aqui sobre esse algoritmo pra explicar melhor...

Até mais!!
Título: Re:Possibilidade de "find and replace" uma lista de hexadecimais
Enviado por: Snow online Outubro 03, 2018, 13:39:13 PM
kuroi, boa tarde, vlw a atenção.. o que acontece é que tenho uma noção básica de Linguagem C somente... estou lendo exatamente o seu livro sobre Romhacking (que é muito bem explicado, acho que todos que têm interesse em criar ferramentas para romhacking deveriam ler) para compreender como faz a leitura e a escrita no arquivo binário sem ter problemas.

A ideia que tive foi exatamente como você mencionou, agora falta transferir isso pra linguagem C.

Eu consegui isso:
{000A35D8}
O homem veio da galinha,{0A}
mas a galinha nega{0A}
paternidade.{00}


mas de uma maneira alternativa, usando um Extrator gringo, e a partir daí, usando o Excel (o qual domino bem) eu consigo a lista de ponteiros Originais e a Lista de ponteiros Modificados de forma automática, assim pelo menos eu só tenho que fazer o "replace".

Então o que eu to pensando basicamente é um programa simples pra fazer o seguinte:

1.
Ler arquivo original (para percorrer no intervalo de texto)
Ler o arquivo traduzido (para percorrer no intervalo de texto)

2.Achei a quebra de cena, no próximo byte pego o offset pra fazer o cálculo do ponteiro. Faço isso nos dois arquivos, assim vou armazenar os dois ponteiros (original e o novo).

3. Busco no arquivo modificado o ponteiro original, substituo pelo ponteiro novo..

Acredito ser essa lógica... 

Título: Re:Possibilidade de "find and replace" uma lista de hexadecimais
Enviado por: kuroi online Outubro 03, 2018, 18:51:59 PM

void Dumper(){

FILE *arquivo, *arquivo_saida;
unsigned int Offset_inicio, Offset_fim;
unsigned int OffsetInicioPonteiros = 0x00;//Inicio do arquivo
unsigned int OffsetFimPonteiros = 0xFFFFF;//Fim do arquivo
unsigned int Byte1, Byte2, Byte3, Byte4;

//Abre o arquivo de leitura       
arquivo = fopen("seujogo.bin", "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);

//Le 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);

//Inicio do loop que ira ler cada byte do arquivo
for(i=Offset_inicio;i<=Offset_fim;i++){
       
//Primeiro dialogo
    if(i == Offset_inicio){

//Quebra o endereço atual em quatro Bytes
Byte4 = (unsigned char)(i & 0x000000FF);
Byte3 = (unsigned char)((i>>8) & 0x000000FF);
Byte2 = (unsigned char)((i>>16) & 0x000000FF);
Byte1 = (unsigned char)((i>>24) & 0x000000FF);

//Verifica se os quatro Bytes foram encontrados em sequencia dentro de todo o arquivo binário
for(j=OffsetInicioPonteiros;j<=OffsetFimPonteiros;j++){

if((Byte1 == memoria[j]) && (Byte2 == memoria[j+1]) && (Byte3 == memoria[j+2]) && (Byte4 == memoria[j+3])){
//Se encontrar, gravar o endereço dele no arquivo de saída (no header do script)
fprintf(arquivo_saida, "{%.8x}\n", j);
break;
}
}
}
//Segundo dialogo (Faz a mesma coisa, porém do segundo diálogo em diante)
if(memoria[i-1] == 0x00){
Byte4 = (unsigned char)(i & 0x000000FF);
Byte3 = (unsigned char)((i>>8) & 0x000000FF);
Byte2 = (unsigned char)((i>>16) & 0x000000FF);
Byte1 = (unsigned char)((i>>24) & 0x000000FF);

for(j=OffsetInicioPonteiros;j<=OffsetFimPonteiros;j++){

if((Byte1 == memoria[j]) && (Byte2 == memoria[j+1]) && (Byte3 == memoria[j+2]) && (Byte4 == memoria[j+3])){

fprintf(arquivo_saida, "{%.8x}\n", j);
break;
}
}
}

//Continuar o Dumper...
}
}

//Trecho do inserter que faz a parte da troca dos ponteiros
void Inserter(){

//Loop que ira ler cada linha do arquivo de texto
while (fgets(s, 100, arq) != NULL){

//Ignorar os separadores de script
if(!strcmp(s, "----------------\n") || !strcmp(s, "----------------")){
continue;
}

//Ler o arquivo de texto Byte por Byte
for(i=0;i<(int)strlen(s)-1;i++){

//Verificar se foi encontrado uma abertura de chaves
if(s[i] == '{'){

//Verificar se foi encontrado um fechamento de chaves depois do terceiro caractere
if(s[i+3] == '}'){

//Gravar o Hexadecimal de dentro das chaves
sscanf(&s[i+1], "%XX", &c);
fputc(c,out);

//Verificar se o Byte lido no arquivo de texto (Dump) é uma quebra de linha
if(c == 0x00 && s[i+4] == 0x0A){

//Se for uma quebra de linha, usar a função ftell() para retornar a posição atual do arquivo binário e alocá-la na variável ponteiro_mod. Esse será o valor do novo ponteiro.
ponteiro_mod = ftell(out);
}

//Somar mais 3 no iterador para continuar no Byte seguinte
i= i+3;
}

//Ao encontrar um ponteiro no header do script
if(s[i+9] == '}'){

//Alocar o ponteiro na variável ponteiro_orig
sscanf(&s[i+1], "%X", &ponteiro_orig);

//E chamar a função calcula_ponteiro() passando por parametro o nome do arquivo binário, o ponteiro_orig e o ponteiro_mod
calcula_ponteiro(nome, ponteiro_orig, ponteiro_mod);

//Somar mais 9 posições no iterador
i=i+9;
}
}
else{

//Se não houver nenhum ponteiro ou Byte de controle mais para ler, gravar os caracteres encontrados no arquivo de texto dentro do binário
c = s[i];
                fputc (cont, out);
}
}
}

void calcula_ponteiro(char* arquivo_mod, unsigned int ponteiro, unsigned int ponteiro_mod){

FILE *arquivo;
unsigned int Byte1, Byte2, Byte3, Byte4;

//Proteger para que não entrem ponteiros zerados na função
if(ponteiro != 0x00 && ponteiro_mod != 0x00){

//Abrir o arquivo binário para leitura e escrita
arquivo = fopen(arquivo_mod, "r+b");

//Separar os Bytes do ponteiro_mod
Byte1 = (unsigned char)(ponteiro_mod & 0x000000FF);
    Byte2 = (unsigned char)((ponteiro_mod>>8) & 0x000000FF);
    Byte3 = (unsigned char)((ponteiro_mod>>16) & 0x000000FF);
    Byte4 = (unsigned char)((ponteiro_mod>>24) & 0x000000FF);

//Seguir até a posição binária do endereço do ponteiro original
fseek (arquivo, OFFSET+ponteiro, SEEK_SET);

//Gravar os quatro Bytes separados anteriormente na posição do ponteiro original
    fwrite(&Byte4, sizeof(unsigned char), 1, arquivo);
  fwrite(&Byte3, sizeof(unsigned char), 1, arquivo);
    fwrite(&Byte2, sizeof(unsigned char), 1, arquivo);   
    fwrite(&Byte1, sizeof(unsigned char), 1, arquivo);

//Fechamento do arquivo binário
    fclose(arquivo);
}
}


Acho que é isso... Dá uma estudada aí e adapta pras suas necessidades.

Até mais!!
Título: Re:Possibilidade de "find and replace" uma lista de hexadecimais
Enviado por: tvtoon online Outubro 03, 2018, 20:42:24 PM
Vou só acrescentar que você pode usar o utilitário Atlas para esses casos problemáticos, mas é o mesmo que aprender programação, logo a escolha fica clara.
Título: Re:Possibilidade de "find and replace" uma lista de hexadecimais
Enviado por: Snow online Outubro 03, 2018, 21:40:09 PM
kuroi, excelente, consegui uma direção estou estudando o funcionamento dessas funções e da lógica usada. Ajudou imensamente..

tvtoon imagino que a resposta é aprender a programar rsrs.. de qualquer forma olharei ele pra ver como funciona...

obrigado pessoal, quando eu conseguir eu dou um retorno..
Título: Re:Possibilidade de "find and replace" uma lista de hexadecimais
Enviado por: Snow online Outubro 07, 2018, 03:47:52 AM
Voltei pra dar um retorno aos colegas que puderam ajudar, estou muito grato..

Eu não mexia com programação tinha uns 10 anos, desde o curso de informática.... suei! mas é incrível como se aprende quando se tem que fazer algo em que realmente está interessado.

kuroiSeu código foi o norte que me faltava, tive que pesquisar manipulação de arquivos, as funções, deslocamento de bits...finalmente depois de fazer testes e ir arrumando a ferramenta saiu...o que eu gastava quase uma hora pra fazer, agora bastam alguns segundos.

A propósito, a única coisa que não compreendi bem como funciona é a parte de deslocamento de bits que você fez:

                        Byte4 = (unsigned char)(i & 0x000000FF);
         Byte3 = (unsigned char)((i>>8) & 0x000000FF);
         Byte2 = (unsigned char)((i>>16) & 0x000000FF);
         Byte1 = (unsigned char)((i>>24) & 0x000000FF);
Deu certinho, mas fiquei sem compreender bem o significado..


Título: Re:Possibilidade de "find and replace" uma lista de hexadecimais
Enviado por: tvtoon online Outubro 07, 2018, 11:18:51 AM
Isso serve para separar os valores de um tipo inteiro (4 bytes) em unidades de bytes. É uma "máscara", como é conhecida.

Se for usar assim, é recomendável misturar no laço próximo: shift por 8 vezes i.
Título: Re:Possibilidade de "find and replace" uma lista de hexadecimais
Enviado por: kuroi online Outubro 07, 2018, 13:32:28 PM
Eai, cara!
Então... Esse conteúdo eu explico em detalhes no meu manual da página 99 até a página 109...

Qualquer dúvida é só me perguntar aqui!

Até mais!!