JMP para o endereço absoluto (códigos op)
-
20-09-2019 - |
Pergunta
Eu estou tentando código de um exe packer/protetor, como uma forma de aprender mais sobre o assembler, c++, e como PE arquivos de trabalho.Eu atualmente tenho que trabalhar para a seção que contém o EP é XORed com uma chave e uma nova seção é criado que contém o meu código de desencriptação.Tudo funciona muito bem, exceto quando tento JMP para o original EP depois de descriptografia.
Basicamente, eu faço isso:
DWORD originalEntryPoint = optionalHeader->AddressOfEntryPoint;
// -- snip -- //
crypted.put(0xE9);
crypted.write((char*)&orginalEntryPoint, sizeof(DWORD));
Mas em vez de saltar para o ponto de entrada, o ollydbg mostra que este código desmonta a:
00404030 .-E9 00100000 JMP 00405035 ; should be 00401000 =[
e quando eu tentar alterá-lo manualmente no olly o novo código de operação mostra-se como
00404030 -E9 CBCFFFFF JMP crypted.00401000
Onde é que 0xCBCFFFFF vem?Como eu poderia gerar a partir do lado do C++?
Solução
eu penso isso E9
é um código de opção para um salto relativo: seu operando especifica uma distância relativa a ser saltada, mais ou menos desde o início da próxima instrução.
Se você deseja que o operando especifique um endereço absoluto, precisará de um código opcão diferente.
Outras dicas
você poderia usar:
mov eax,DESTINATION_VA
jmp eax ; pick any register the destination doesn't care about
ou
push DESTINATION_VA
ret ; not recommended for performance
Isso e o próximo até 16 ret
As instruções que remontam à árvore de chamadas mais altas do que essa profundidade pretenderão incorretamente, a menos que tenham sido empurradas para fora da pilha preditora de retorno-endereço por uma profundidade de chamada mais profunda. (As CPUs atuais normalmente têm uma pilha preditora de 16 entradas).
relativo E9
jmp
A codificação é usada assim:
CURRENT_RVA: jmp (DESTINATION_RVA - CURRENT_RVA - 5 [sizeof(E9 xx xx xx xx)])
push + ret é a menor solução se você tiver endereço VA e a imagem não é realocada, mas ainda são 6 bytes, por isso é maior que um direto jmp rel32
.
O registro-indireto é provavelmente o mais eficiente se você não puder usar um direto normal jmp
.
opcode absoluta indireta salto é FF + 4byte endereço.Este é o mais usado frequentemente para jumptables de endereços armazenados em dados.
Endereços absolutos não necessitam de deslocalização, quando não carregado para o endereço esperado, de modo relativo endereços são geralmente preferidos.Código relativo saltos também é 2 bytes de tamanho menor.
Intel otimização manual indica que a cpu espera call e ret para ser usado em pares, de modo que o ret sem uma chamada sugerido na resposta 2 iria fazer com que eles chamam de uma "penalidade de desempenho".
Além disso, se o código não foi carregado para o mesmo endereço que o compilador assumido, o ret seria, provavelmente, a falha do programa.Seria mais seguro para calcular um endereço relativo.