[Dúvida] Como gravar sem usar APIs

Iniciado por Anonymous, 08 de Outubro , 2006, 03:18:57 PM

tópico anterior - próximo tópico

0 Membros e 1 Visitante estão vendo este tópico.

Anonymous

É o seguinte, to tentando fazer um keylogger, e tenho umas dúvidas:
1. Tem como mover o registrador de 8 bits al para o de 32 bits eax ?
2. Como gravar em um arquivo um registrador de 8 bits sem usar funções API ?
3. Quais as diferenfas do comando lea e mov ?
4. É diferente fazer lea ax,bx e mov ax,bx ?

Quem conseguir responder pelo menos uma das dúvidas, já estou muito grato.

caesar2k

bom cara, eu também tenho as mesmas dúvidas... to começando com NASM aqui, e até hoje eu não entendo o que o LEA faz, com uma função de "load effective address", não faço a mínima idéia XD

vuln

Posso estar perdido no mundo mas acho que a sua relação está meio incorreta. NASM é o Compilador não? De qualquer modo, ao menos ao meu ponto de vista, você está tratando o NASM como uma linguagem a parte.  ???
"O amor por princípio, a Ordem por base, o progresso por objetivo."

Anonymous

É verdade vuln, NASM é um compilador.
Mas alguns compiladores mudam um pouco a forma de escrever em assembly, não a linguagem em si, mas o jeito de usa-la.

É meio estranho de explicar mesmo, procure no Google exemplos de como fazer um hello world com o NASM e compare com o FASM.

Dark_Side

Hi,

Tentarei explicar de acordo com minhas concepções e nível de conhecimento atuais. Leve em conta que eu sou iniciante em Assembly e o que eu passar pode não estar correto ;)

1. Tem como mover o registrador de 8 bits al para o de 32 bits eax ?

 Os registradores AL, AH, AX e EAX, podem ser considerados como apenas um: o Acumulador.

Na verdade, esses registradores têm tamanhos diferentes:

AL - 8 bits;
AH - 8 bits;
AX - 16 bits;
EAX - 32 bits;

Os dois primeiros (AL e AH) são subdivisões do registrador AX: AL é o byte baixo (bits: 0 a 7) e AH o byte alto (bits: 8 a 15). O registrador EAX é uma extensão para 32 bits (bits: 0 a 31).


Lolz, já vou avisar que eu não sei desenhar, então nem pode zuar meu esquema:

_____________________________ EAX
  AL      AH
_______|_______|     
               AX   
   

O registrador EAX começa no bit 0 e termina no bit 31;
O regitrador AX começa no bit 0 e termina no bit 15;
Temos ainda dentro do registrador AX: AL = 0 até 7 e AH = 8 até 15;

Vamos supor que temos:

mov al,11b

Estamos movendo o valor binário 11 para o byte baixo de AX, que é AL.

Considerando que EAX é 0, seu valor seria:

0x0000011b
       |
       AL

Sabendo-se que o bit mais significativo é 1, o valor de EAX seria 0x11b, o mesmo valor de AL.

Portanto, para que EAX tenha o valor de AL, basta zerá-lo antes de mover para AL o respectivo valor:

xor eax,eax ; Zera EAX
mov al,valor

Com o trecho acima, o valor de EAX seria o mesmo movido para AL.

Este processo se faz necessário pois AL possui 8 bits e se os bits superiores (8 a 31) de EAX não forem 0, ou seja, forem significativos, o registrador EAX como um todo terá outro valor.

Exemplo:

mov eax,2048 ; EAX = 2048 = 100000000000b

Em binário, o valor de EAX seria:

0x100000000000b

Se não zerarmos EAX e fizermos:

mov al,4 ; AL = 4 = 100b

O registrador EAX teria agora o seguinte valor (binário):

0x100000000100b
           |
           100b -> AL

O valor de EAX portanto, seria 2052 em decimal e não 4.

A página abaixo explica mais sobre registradores:

http://www.powerbasic.com/support/help/ ... isters.htm


-----------------------------------------------------------------------


2. Como gravar em um arquivo um registrador de 8 bits sem usar funções API ?

Pode-se utilizar em conjunto as interrupções: "21,3C", "21,40" e "21,3E".

Exemplo no FASM:

org 100h ; Origem -> endereço 256

;Cria o arquivo: lol.txt

mov ah,3ch  ; AH = 3CH
mov cx,0 ; CX = 0;
mov dx,arq ; DX = ponteiro para o buffer que contém o nome do arquivo
int 21h ; 21,3C

; Move para bx o ponteiro para o arquivo criado
mov bx,ax


; Escrever no arquivo o caractere em AL

mov ah, 40h ; AH = 40h
mov cx,1 ; Bytes a serem escritos -> 1 caractere = 1 byte

mov al,'S' ; Move para AL -> 'X' -> caractere a ser escrito
mov [char],al ; Move para o primeiro caractere do buffer o valor de AL
mov dx,char ; Move para DX o ponteiro para o buffer
int 21h ;21,40

; Fecha o arquivo

mov ah,3eh-> AH = 3Eh
int 21h ;21,3E

mov ax,0x4C00 ; AH = 4C, AL = 0
int 21h ; 21,4C  ; Encerra

char db  0,0 ; Buffer que a escrever no arquivo
arq db "lol.txt",0   ; Nome do arquivo a ser criado


Note que a interrupção 21,40 é utilizada para escrever uma string em um arquivo. Utilizamos o buffer "char" como string. Movemos para o primeiro byte do buffer "char" o caractere em AL, para que só assim possa ser escrito posteriormente.


-----------------------------------------------------------------------

3. Quais as diferenças do comando lea e mov ?

Geralmente, a instrução MOV é utilizada para mover valores para registradores, exemplo:

mov cx,1000 ;cx = 1000

A instrução LEA é utilizada para mover endereços de variáveis, ou seja, um ponteiro. Exemplo:

lea dx,buffer ; Move para DX o endereço de "buffer
buffer db "Buffer!",0

Dependendo do assembler, as instruções LEA e MOV podem assumir papeis diferentes, em alguns casos, a instrução LEA nem mesmo é reconhecida como instrução válida, no FASM por exemplo:

mov dx,buffer ; Move para DX o endereço de "buffer"
buffer db "Buffer!",0

Ainda no FASM:

; O FASM considera a instrução LEA como inválida
lea dx,buffer
buffer db "Buffer!",0

A instrução MOV assume o papel da instrução LEA, movendo para DX o endereço de "buffer".

-----------------------------------------------------------------------

4. É diferente fazer lea ax,bx e mov ax,bx ?

Seria diferente sim. Enquanto a instrução LEA move endereços, a instrução MOV, geralmente, move valores.

Pode-se no entanto, fazer com que MOV mova endereços:

mov dx,OFFSET buffer ; Move para DX o endereço de buffer
buffer db "Buffer!",0

Equivale a:

lea dx,buffer ; Move para DX o endereço de buffer
buffer db "Buffer!",0

O uso de LEA e MOV pode ser diferente dependendo do compilador em questão.

-----------------------------------------------------------------------


Aproveitando o post acima, um Hello World feito no NASM, seria basicamente o seguinte:

[ORG 0x100] ; endereço de memória 256
mov ah,9 ; ah = 9 (escrever string na tela
mov dx,msg ; move para DX o ponteiro para a string
int 21h ; chama interrupção 21,9

mov ax,0X4C00 ; AH = 4C; AL = 0
int 21h; interrupção 21,4C -> sair do programa

msg db "Hello World!$" ; Buffer a ser escrito na tela

Lolz... eu acho que é isso.

Bye ;)

Anonymous

Outras dúvidas:

1.  Para que serve o comando ORG?
2. Um dia eu vi um exemplo de Hello World em assembly assim:org 0x100
mov ah,9
mov dx,OFFSET hello ;[ Essa á a parte que eu não entendo ];
int 0x21

mov ax,0x4C00
int 0x21

hello:
db 'Hello World!$'

Como funciona isso?

Anonymous

@Sthealt

Exemplo:

org $1000
Define o endereço $1000 ( em hexadecimal ) como inicioda área do programa, na memória.

Byee...

Anonymous


Dark_Side

Hi,
Você deve especificar o endereço de memória no qual o programa deve ser carregado, pois o compilador precisa dessa  origem para especificar por exemplo, ponteiros e variáveis.
Bye.

Anonymous

Em um Hello World, é preciso colocar org 0x100 (256 em decimal né?) se colocarmos por exemplo 0x101 não iria funcionar?

Dark_Side

Hi,
Se você fizer org 0x101 (dec 247) você está especificando para que o programa seja carregado no endereço 0x101. Uma vez em que um programa DOS (16 bits) deve iniciar no endereço 0x100,  um valor diferente culminaria com a não execução do programa.

Bye ;)

Anonymous

Outra coisa, tem como usar registradores 32 bits no DOS?
E se tem como fazer em um programa 32 bits, usar uma API e depois um hello world em DOS?