Questão:
Alguma correlação entre o prefixo do segmento do programa DOS e o endereço base do executável carregado?
ScumCoder
2014-08-10 17:16:13 UTC
view on stackexchange narkive permalink

Estou usando o IDA para desmontar o Test Drive III. É um jogo DOS de 1990. O * .EXE tem formato MZ.

O jogo usa uma série de recursos anti-reversão, como copiar seu código para o segmento (PSPseg + 2be7) onde PSPseg é o valor inicial de ES (ou seja, o segmento onde o PSP reside). Pelo que eu sei, os executáveis ​​COM são sempre carregados logo após o final do Prefixo do segmento do programa (PSP) , de modo que tanto o PSP quanto o exe caber em um segmento. E quanto aos executáveis ​​MZ? Existe algum lugar fixo onde o PSP do aplicativo está localizado em relação ao próprio aplicativo?

Em outras palavras, o deslocamento PSPseg de base é sempre o mesmo? No meu DOSBox no início da execução do programa, CS é sempre 0x22CF , ES = DS = 0x01FE , CS0 no cabeçalho MZ é 0x20C1 , gerando PSPseg offset 0x0010 (16 segmentos, 256 bytes - exatamente o tamanho do PSP).

Se esse deslocamento não for fixo e o PSP e o aplicativo forem carregados aleatoriamente em qualquer local de memória grande o suficiente, há pelo menos alguma garantia sobre seus endereços? Como se o endereço PSP fosse sempre inferior ao endereço base do aplicativo?

Quatro respostas:
Guntram Blohm supports Monica
2014-08-11 12:18:16 UTC
view on stackexchange narkive permalink

O DOS não tinha o conceito de que mais de um aplicativo pudesse ser executado ao mesmo tempo, com cada um desses aplicativos capaz de alocar memória. Os programas que permaneceram residentes após o encerramento não conseguiram alocar mais memória enquanto outro programa estava em execução. Portanto, não houve fragmentação na memória, e nenhum "local de memória que era grande o suficiente".

A memória de 0x00000 foi ocupada pela tabela de vetor de interrupção e várias variáveis ​​do BIOS, DOS carregados atrás deles. O fim do bloco de memória usado pelo DOS dependia de vários fatores, mas sempre que um programa era carregado, o PSP era criado no local mais baixo possível e o programa carregado diretamente atrás dele. Então, sim, você pode confiar em seu programa usando a memória por trás do PSP, e você pode confiar na diferença entre seus registradores de segmento e o PSP sendo constante também.

O próprio segmento PSP era imprevisível para programadores - coisas como o driver do console ansi.sys, drivers de teclado externos, drivers Cdrom e vários programas residentes (alguém se lembra do companheiro?) podem aumentar o tamanho do "bloco dos", fazendo com que o endereço PSP dos programas carregados aumente (e a memória disponível para diminuir). Mas, desde que você não mude a configuração de seu DOSBOX, você deve poder contar com o PSP - e seus registradores de segmento - sendo o mesmo para cada execução do programa.

Igor Skochinsky
2014-08-11 00:49:47 UTC
view on stackexchange narkive permalink

Os executáveis ​​no formato MZ também têm o PSP em CS-0x10 logo antes dos dados carregados do arquivo.

Citando Ajuda técnica!, provavelmente a melhor referência de programação DOS:

Os programas em formato EXE definem vários segmentos de programa, incluindo um código, dados e segmento de pilha. O arquivo EXE é carregado a partir de PSP: 0100.

que deve dizer "DS-0x10". MZ CS pode estar em algum lugar longe do PSP.
Obrigado Peter, mas o DS deve apontar para o PSP. Espero que minha edição esteja melhor agora.
Geoff Chappell
2014-08-29 19:37:25 UTC
view on stackexchange narkive permalink

É tipicamente verdade que o DOS carrega um programa .EXE imediatamente após o PSP, significando em seus termos essa base - PSP == 0x0010 . Mas não é necessariamente verdade, e se você estava escrevendo este (ou qualquer outro) executável DOS, seria melhor saber disso. No entanto, este não é você. Em vez disso, aqui, você é um engenheiro reverso - ou pelo menos tentando ser um. O que conta, portanto, não é o que é verdadeiro para o DOS em geral, mas o que estava na mente do programador, certo ou errado, para o executável específico que você está estudando.

Se este programa está realocando parte de seu código para um segmento que ele calcula, adicionando o que eu considero que você significa um 0x2BE7 embutido em código para PSPseg , então o programador provavelmente estava contando com o endereço base de seu programa como PSPseg + 0x0010 . Obviamente, uma compreensão mais precisa de onde vem 0x2BE7 pode mostrar que o programador foi mais cuidadoso. Não que eu tenha feito a engenharia reversa de qualquer código DOS em muito, muito tempo, mas me lembro que mapear a segmentação do programa (incluindo suas permissões para dados não inicializados, heap e pilha) costumava ser uma preparação útil.

Agora, no geral ... O que quer que seja dito em "provavelmente a melhor referência de programação DOS", um programador DOS não deve confiar no material do programa para ser carregado imediatamente após o PSP. Embora seja verdade com uma frequência esmagadora na prática, um caso excepcional existe e é: primeiro, documentado, embora obscuramente; e segundo, não está totalmente sob o controle do programador.

O caso surge quando o e_maxalloc membro do IMAGE_DOS_HEADER é zero. Isso pode ser definido no momento do link, mas também posteriormente por meio de ferramentas como EXEHDR . O DOS interpreta zero para este membro como uma direção para organizar o programa de uma maneira incomum dentro de qualquer bloco de memória que o DOS encontrou para carregar o programa. O PSP vai para a base, como de costume, mas o material do programa é colocado o mais alto possível dentro do bloco. O espaço entre não foi inicializado.

alfgaar
2016-01-20 08:12:02 UTC
view on stackexchange narkive permalink

O PSP é uma tabela de processos, contém informações sobre um processo em execução (aplicativo), é criado e preenchido pelo carregador. O carregador usa as informações EXEHDR para preencher alguns dos campos do PSP e outros. Depois de criar o PSP, o carregador pega o código do aplicativo (o que vier depois do EXEHDR até o final do arquivo e carrega logo após o PSP.

O PSP ocupa o início de um aplicativo (COM e EXE) memória alocada; o deslocamento PSP no segmento é sempre 0000H - 100H. Quando seu aplicativo é iniciado, os segmentos DS e ES apontam para PSP, você deve ajustá-los ao segmento de dados do aplicativo antes de continuar.

Os segmentos são não fixos, eles são definidos com base no espaço de memória livre, mas os deslocamentos dentro de um segmento são sempre os mesmos, caso contrário, seu aplicativo quebraria, todos os seus dados e código são definidos (calculados) com base nos deslocamentos desde o início de um segmento.

CS é preenchido pelo carregador após alocar memória e carregar seu programa, IP também é preenchido pelo carregador, esta informação é extraída do EXEHDR (o deslocamento do ponto de entrada do aplicativo (é calculado pelo montador / compilador quando ele cria o código do objeto), mas é definido pelo programador em assembly, é o rótulo definido após a diretiva END no masm, ou pelo compilador, em c é o deslocamento da função principal).



Estas perguntas e respostas foram traduzidas automaticamente do idioma inglês.O conteúdo original está disponível em stackexchange, que agradecemos pela licença cc by-sa 3.0 sob a qual é distribuído.
Loading...