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++?

Foi útil?

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.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top