Release on on 27th May 2014, 22:32
Muitas pessoas estavam pedindo um tutorial aobscan então aqui eu faço uma breve descrição para usar aobscan.
Por que estamos usando aobscan com freqüência?
Em muitos casos, o endereço do código que queremos mudar não é estática. Isso pode acontecer em muitos jogos
onde os códigos são carregados somente quando eles são usados e também acontece se você não está usando o mesmo
versão do jogo. Código Ifthe si não mudou, apenas o endereço do código, você pode usar aobscan para encontrar o endereço do código.
Primeiro vou começar com um exemplo onde eu mostro como você pode mudar um simples script em um script aobscan,
então eu vou explicar em mais detalhes para aqueles que querem saber como ele está trabalhando. No final eu vou escrever
algumas dicas mais avançadas para os problemas específicos que podem ocorrer quando você estiver usando aobscan.
O processo de destino é o programa Tutorial para CE 6.2. Aqui está um script normal que vai resolver Passo 2
do tutorial (neste ponto eu suponho que você pode fazer truques com endereços de código estático).
- Code:
[ENABLE]
//code from here to '[DISABLE]' will be used to enable the cheat
alloc(newmem,2048) //2kb should be enough
label(returnhere)
label(originalcode)
label(exit)
newmem: //this is allocated memory, you have read,write,execute access
mov [ebx+00000464],(int)1000
originalcode:
mov eax,[ebx+00000464]
exit:
jmp returnhere
"Tutorial-i386.exe"+22988:
jmp newmem
nop
returnhere:
[DISABLE]
//code from here till the end of the code will be used to disable the cheat
dealloc(newmem)
"Tutorial-i386.exe"+22988:
mov eax,[ebx+00000464]
//Alt: db 8B 83 64 04 00 00
Para mudar isso em um script com aobscan, você tem que fazer apenas algumas modificações (olhar para os comentários):
- Code:
[ENABLE]
//code from here to '[DISABLE]' will be used to enable the cheat
alloc(newmem,2048) //2kb should be enough
label(returnhere)
label(originalcode)
label(exit)
label(whatever) //make a label that you can use for your aobscan
registersymbol(whatever) //also register it as a symbol
aobscan(aob1,8B 83 64 04 00 00 3D) //use aobscan to search for the code, more explanation later
newmem: //this is allocated memory, you have read,write,execute access
mov [ebx+00000464],(int)1000
originalcode:
mov eax,[ebx+00000464]
exit:
jmp returnhere
aob1: //replace the static address with your aobscan, which is called aob1 in my case
whatever: //store aob1 on the whatever label
jmp newmem
nop
returnhere:
[DISABLE]
//code from here till the end of the code will be used to disable the cheat
dealloc(newmem)
whatever: //replace the static address with the whatever label
db 8B 83 64 04 00 00 //restore the original byte pattern
unregistersymbol(whatever) //we don't need this symbol anymore so unregister it
Se você copiar e colar este script em CE, ele procurará o código que eu mudei no roteiro original
e fazer o mesmo a injeção de código. Agora devo explicar algumas coisas em mais detalhes, embora não seja realmente
neccessary para entender tudo em ordem para usar aobscan.
- Code:
Tutorial-i386.exe+22988 - 8B 83 64040000 - mov eax,[ebx+00000464]
Tutorial-i386.exe+2298E - 3D E8030000 - cmp eax,000003E8
Se você olhar para ele no disassembler, você pode ver como é esta instrução armazenada na memória.
- Code:
8B 83 64 04 00 00
3D E8 03 00 00
Você tem que chegar a um padrão que irá identificar este código. Vamos fazer isso:
Tipo de valor Mudar para 'Array of byte', certifique-se de que a caixa 'gravável' é apenas 'opcional' e que não tem
uma marca de verificação, como o código que está procurando não é gravável, só executável. Agora, digitalize para este padrão de byte
- Code:
8B 83 64 04 00 00
Você provavelmente terá 8 resultados, que não é um bom começo e se você verificar o primeiro resultado, não é o
código correto que estamos procurando. Assim, podemos ver que não podemos usar esse padrão de byte. Agora, temos de chegar a um novo padrão que vai filtrar os sete resultados errados. Como podemos ver, o primeiro byte da próxima instrução
inicia com o 3D. Tente procurar por esse padrão de bytes:
- Code:
8B 83 64 04 00 00 3D
Agora você terá um resultado, ou pelo menos o primeiro será o código que você está procurando. Este byte
padrão pode ser usado para encontrar o endereço do nosso código. A sintaxe é muito simples
- Code:
aobscan(name,byte pattern)
aobscan(aob1,8B 83 64 04 00 00 3D)
O nome dos aobscans e símbolos podem ser qualquer coisa, cabe a você. Após essa instrução é executada,
aob1 é igual a 'Tutorial-i386.exe' 22988 endereço. Você pode usar aob1 para se referir a este endereço.
NOTA: O caractere * é um personagem Coringa. Se você colocar * em seu padrão de byte, que pode ser qualquer coisa.
Eg
'* 83 64 04 00 00 3D' pode ser qualquer coisa de '00 83 64 04 00 00 3D' para '83 64 FF 04 00 00 3D'
Quando você não tem certeza de que um byte será o mesmo em outras versões do jogo, use *.
Fazendo o script:
Como você vê que era necessário marcar para fazer algumas modificações no roteiro original de usar aobscan. Você pode apenas
copiar e colar essas mudanças em seu roteiro, sem jamais perguntar por que eles são necessários, mas se você está curioso, aqui
são as razões.
- Code:
label(whatever)
registersymbol(whatever)
Você não é capaz de usar seu resultado aobscan na seção disable e você não pode fazer a varredura do código de qualquer um, porque você mudou com sua injeção de código. É por isso que o endereço tem que ser salvo em algum lugar para uso posterior.
- Code:
aob1: //replace the static address with your aobscan, which is called aob1 in my case
whatever: //store aob1 on the whatever label
Esta é a parte onde armazenamos aob1 no 'qualquer' símbolo para que possamos usá-lo na seção desativar também.
Disable section
- Code:
whatever: //replace the static address with the whatever label
É por isso que salvou o endereço em 'o que', precisamos restaurar o código original na seção desativar.
- Code:
db 8B 83 64 04 00 00 //restore the original byte pattern
Sim. Tenho substituído
- Code:
mov eax,[ebx+00000464]
//Alt: db 8B 83 64 04 00 00
com o padrão de byte inicial. A razão é que a instrução pode ser compilado de forma diferente por CE e temos que estar 100% certo para restaurar as instruções exatamente como era.
Example:
- Code:
mov eax,[ebx+ecx++00000464]
and
mov eax,[ecx+ebx++00000464]
unregistersymbol (whatever) // não precisamos de mais este símbolo tão anular o seu registo
Simples limpeza. Remova o símbolo de que não estamos usando mais.
Dicas avançadas e soluções para os vários problemas que podem ocorrer quando você estiver usando aobscan:
Os erros mais comuns com aobscan estão usando os mesmos nomes de símbolos quando você tem mais do que um script e não restaurar o código original corretamente. Você deve sempre usar símbolos / etiqueta / nomes aobscan separadas em diferentes roteiros e como eu disse acima, ter 100% de certeza de que você haverestored o padrão de byte original. Se seus scripts estão funcionando corretamente, eles podem ser ligado / desligado a qualquer momento de forma independente, sem interferir com o outro. É fácil cometer erros e os usuários muitas vezes culpam CE por algum bug, mas se você seguiu as instruções corretamente, ele deve funcionar. O erro está no seu script, em algum lugar algo é asneira. Confira tudo, olhar para as mudanças no disassembler quando você virar as fraudes on / off, verifique o código original eo código restaurado que eles realmente estão combinando etc
Certifique-se de que o seu padrão de byte não está contendo endereços estáticos ou outros códigos que vai mudar mais provável
em outras versões do jogo. Por exemplo, um código como
- Code:
call 00908070
será diferente em outra versão do jogo, porque é 00908070 um endereço estático. Substituir endereços estáticos com * personagem. Cada * é um byte. Assim substituir o endereço com * * * * no padrão.
Como fazer uma injeção de código em um endereço, se você não encontrar um padrão de byte para esse endereço particular?
Vamos supor que queremos mudar este código
- Code:
Tutorial-i386.exe+22988 - 8B 83 64040000 - mov eax,[ebx+00000464]
Tutorial-i386.exe+2298E - 3D E8030000 - cmp eax,000003E8
Tutorial-i386.exe+22993 - 75 2C - jne Tutorial-i386.exe+229C1
e nós temos um padrão de bytes que nos dá '22988 Tutorial-i386.exe' mas queremos fazer a injeção de código neste endereço:
- Code:
Tutorial-i386.exe+2298E - 3D E8030000 - cmp eax,000003E8
Se não encontrar qualquer padrão de byte de trabalho que vai encontrar Tutorial-i386.exe 2298E, podemos usar o padrão de byte anteriormente descobriu que nos dá Tutorial-i386.exe 22988 como o resultado. O código original ficaria assim:
- Code:
[ENABLE]
//code from here to '[DISABLE]' will be used to enable the cheat
alloc(newmem,2048) //2kb should be enough
label(returnhere)
label(originalcode)
label(exit)
newmem: //this is allocated memory, you have read,write,execute access
mov [ebx+00000464],(int)1000
originalcode:
cmp eax,000003E8
exit:
jmp returnhere
"Tutorial-i386.exe"+2298E:
jmp newmem
returnhere:
[DISABLE]
//code from here till the end of the code will be used to disable the cheat
dealloc(newmem)
"Tutorial-i386.exe"+2298E:
cmp eax,000003E8
//Alt: db 3D E8 03 00 00
A versão aobscan será este:
Code:
[ENABLE]
//code from here to '[DISABLE]' will be used to enable the cheat
alloc(newmem,2048) //2kb should be enough
label(returnhere)
label(originalcode)
label(exit)
label(whatever)
registersymbol(whatever)
aobscan(aob1,8B 83 64 04 00 00 3D)
newmem: //this is allocated memory, you have read,write,execute access
mov [ebx+00000464],(int)1000
originalcode:
cmp eax,000003E8
exit:
jmp returnhere
aob1+6: //22988+6 = 2298E so we are making our code injection on 2298E address instead of 22988
whatever:
jmp newmem
returnhere:
[DISABLE]
//code from here till the end of the code will be used to disable the cheat
dealloc(newmem)
whatever:
db 3D E8 03 00 00
unregistersymbol(whatever)
Como você pode ver, temos utilizado o padrão de byte que nos dá Tutorial-i386.exe 22988 como resultado, mas desde que nós queremos fazer a injeção de código em 2298E, nós simplesmente usado aob1 6 em vez de aob1. 22988 6 = 2298E e desde aob1 = 22988, aob1 6 também é igual a 2298E.
Saltos em seu script:
Instruções de salto no código original vai causar problemas para você, se você não tratá-los adequadamente. A fonte do problema é a seguinte:
- Code:
Tutorial-i386.exe+22988 - 8B 83 64040000 - mov eax,[ebx+00000464]
Tutorial-i386.exe+2298E - 3D E8030000 - cmp eax,000003E8
Tutorial-i386.exe+22993 - 75 2C - jne Tutorial-i386.exe+229C1
Tutorial-i386.exe+22995 - 8B 83 4C040000 - mov eax,[ebx+0000044C]
CE vai mostrar que salto condicional como JNE Tutorial-i386.exe 229C1 para facilitar as coisas, mas, na realidade, que a instrução é 2C JNE. Ele vai saltar para a frente 2C bytes.
O que acontece se você usar esse código?
- Code:
[ENABLE]
//code from here to '[DISABLE]' will be used to enable the cheat
alloc(newmem,2048) //2kb should be enough
label(returnhere)
label(originalcode)
label(exit)
newmem: //this is allocated memory, you have read,write,execute access
//place your code here
originalcode:
jne Tutorial-i386.exe+229C1
mov eax,[ebx+0000044C]
exit:
jmp returnhere
"Tutorial-i386.exe"+22993:
jmp newmem
nop
nop
nop
returnhere:
[DISABLE]
//code from here till the end of the code will be used to disable the cheat
dealloc(newmem)
"Tutorial-i386.exe"+22993:
jne Tutorial-i386.exe+229C1
mov eax,[ebx+0000044C]
//Alt: db 75 2C 8B 83 4C 04 00 00
Será que vai funcionar? Absolutamente. O problema é que Tutorial-i386.exe 229C1 é um endereço estático e você não pode saltar para um endereço estático, porque vai ser diferente em outras versões do jogo. Este salto vai funcionar quando você está fazendo um script normal, mas você não pode usá-lo com aobscan.
Então, vamos substituí-lo com a instrução original JNE +2C.
- Code:
[ENABLE]
//code from here to '[DISABLE]' will be used to enable the cheat
alloc(newmem,2048) //2kb should be enough
label(returnhere)
label(originalcode)
label(exit)
newmem: //this is allocated memory, you have read,write,execute access
//place your code here
originalcode:
jne +2C
mov eax,[ebx+0000044C]
exit:
jmp returnhere
"Tutorial-i386.exe"+22993:
jmp newmem
nop
nop
nop
returnhere:
[DISABLE]
//code from here till the end of the code will be used to disable the cheat
dealloc(newmem)
"Tutorial-i386.exe"+22993:
jne +2C
mov eax,[ebx+0000044C]
//Alt: db 75 2C 8B 83 4C 04 00 00
O que vai acontecer se você permitir isso? Se você tiver sorte, seu programa não irá falhar. Mas isso não vai funcionar. Porque se você saltar para a frente 2C bytes na memória alocada que você criou, você acaba no meio do nada. Não se esqueça que este salto está calculando o destino da atual endereço por isso, quando você faz uma injeção de código, ele está calculando o salto da memória alocada.
Ok como consertar isso? Em primeiro lugar, precisamos de um padrão de byte para este código.
Código:
75 2C 8B 83 4C 04 00 00
Agora calcule a diferença entre o 'Tutorial-i386.exe' 22993 eo destino do salto, 229C1 Tutorial-i386.exe. A diferença é 2E bytes, o que significa que aob1 2E = Tutorial-i386.exe 229C1.
Por que não 2C? Temos JNE 2C e agora temos 2E. A resposta é que o salto relativo irá calcular o destino a partir do final da instrução e que são o seu cálculo a partir do primeiro byte de instrução. Nossa instrução ocupa 2 bytes, por isso, a diferença é de 2 bytes superior.
Agora que sabemos como devemos mudar o salto, podemos fazer um script que irá saltar para aob1 2E, onde quer que seja encontrado pelo aobscan.
- Code:
[ENABLE]
//code from here to '[DISABLE]' will be used to enable the cheat
alloc(newmem,2048) //2kb should be enough
label(returnhere)
label(originalcode)
label(exit)
label(whatever)
registersymbol(whatever)
aobscan(aob1,75 2C 8B 83 4C 04 00 00)
newmem: //this is allocated memory, you have read,write,execute access
//place your code here
originalcode:
jne aob1+2E
mov eax,[ebx+0000044C]
exit:
jmp returnhere
aob1:
whatever:
jmp newmem
nop
nop
nop
returnhere:
[DISABLE]
//code from here till the end of the code will be used to disable the cheat
dealloc(newmem)
whatever:
db 75 2C 8B 83 4C 04 00 00
unregistersymbol(whatever)
Tada, fizemos um magnífico roteiro que absolutamente não está fazendo nada de útil, mas pelo menos ele está saltando no local certo, apesar do fato de que a própria instrução de salto é muito longe do destino. Agora vamos fazer algo útil e substituir JNE com je. Isto irá resolver o passo 2 do tutorial e você pode avançar para o passo 3.
Neste momento, nada mais me vem à mente sobre o assunto. Isso deve ser o suficiente para lidar com a maior parte dos problemas que irá enfrentar quando você estiver usando aobscan.