sexta-feira, 26 de maio de 2017

Curso de Assembly Aula 17


+---------------+
¦ ASSEMBLY XVII ¦
+---------------+

    Eis  o  arquivo  .ASM com as rotinas para manipulaçäo da memória
expandida:

 +----------------------------------------------------------------+
 ¦  IDEAL                                                         ¦
 ¦  MODEL LARGE,PASCAL                                            ¦
 ¦  LOCALS                                                        ¦
 ¦  JUMPS                                                         ¦
 ¦                                                                ¦
 ¦  GLOBAL  emmGetVersion : PROC                                  ¦
 ¦  GLOBAL  emmGetPageFrameSegment : PROC                         ¦
 ¦  GLOBAL  emmGetAvailablePages : PROC                           ¦
 ¦  GLOBAL  emmAllocPages : PROC                                  ¦
 ¦  GLOBAL  emmFreePages : PROC                                   ¦
 ¦  GLOBAL  emmMapPage : PROC                                     ¦
 ¦  GLOBAL  emmGetError : PROC                                    ¦
 ¦                                                                ¦
 ¦  DATASEG                                                       ¦
 ¦                                                                ¦
 ¦  emmVersion  dw  0                                             ¦
 ¦  emmError    db  0       ; Nenhum erro ainda... :)             ¦
 ¦                                                                ¦
 ¦  CODESEG                                                       ¦
 ¦                                                                ¦
 ¦  ; Obtém a versäo do EMM.                                      ¦
 ¦  ; Devolve no formato 0x0X0Y (onde X é versäo e Y revisäo).    ¦
 ¦  ; Protótipo em C:                                             ¦
 ¦  ;   unsigned pascal emmGetVersion(void);                      ¦
 ¦  PROC    emmGetVersion                                         ¦
 ¦      mov     [emmError],0    ; Inicializa flag de erro...      ¦
 ¦      mov     ah,46h                                            ¦
 ¦      int     67h             ; Invoca o EMM                    ¦
 ¦      or      ah,ah           ; Testa o sucesso da funçäo...    ¦
 ¦      jz      @@no_error                                        ¦
 ¦      mov     [emmError],ah   ; Poe erro no flag...             ¦
 ¦      mov     ax,-1           ; ... e retorna != 0.             ¦
 ¦      jmp     @@done                                            ¦
 ¦      mov     ah,al           ; Prepara formato da versäo.      ¦
 ¦      and     ax,111100001111b ; A funçäo 46h do EMM devolve    ¦
 ¦      mov     [emmVersion],ax  ; no formato BCD... por isso     ¦
 ¦  @@done:                      ; precisamos formatar...         ¦
 ¦      ret                                                       ¦
 ¦  ENDP                                                          ¦
 ¦                                                                ¦
 ¦  ; Funçäo: Obtém o segmento do Page Frame.                     ¦
 ¦  ; Protótipo em C:                                             ¦
 ¦  ;   unsigned pascal emmGetPageFrameSegment(void);             ¦
 ¦  PROC    emmGetPageFrameSegment                                ¦
 ¦      mov     ah,41h      ; Usa a funçäo 41h do EMM             ¦
 ¦      int     67h         ; Chama o EMM                         ¦
 ¦      mov     ax,bx       ; Poe o segmento em AX                ¦
 ¦                          ; Funçäo 41h coloca o segmento do     ¦
 ¦                          ; "Page Frame" em BX.                 ¦
 ¦      ret                                                       ¦
 ¦  ENDP                                                          ¦
 ¦                                                                ¦
 ¦  ; Funçäo: Obtém o número de páginas disponíveis na memória.   ¦
 ¦  ; Protótipo em C:                                             ¦
 ¦  ;   unsigned pascal emmGetAvailablePages(void);               ¦
 ¦  ; Obs:                                                        ¦
 ¦  ;   Näo verifica a ocorrencia de erros... modifique se quiser ¦
 ¦  PROC    emmGetAvailablePages                                  ¦
 ¦      mov     ah,42h                                            ¦
 ¦      int     67h     ; Invoca o EMM.                           ¦
 ¦      mov     ax,bx   ; Poe páginas disponiveis em AX.          ¦
 ¦      ret                                                       ¦
 ¦  ENDP                                                          ¦
 ¦                                                                ¦
 ¦  ; Aloca páginas e devolve handle.                             ¦
 ¦  ; Protótipo em C:                                             ¦
 ¦  ;   int pascal emmGetAvailablePages(unsigned Pages);          ¦
 ¦  ; Obs: Devolve -1 se houve erro na alocaçao e seta            ¦
 ¦  ;      a variável emmError.                                   ¦
 ¦  PROC    emmAllocPages                                         ¦
 ¦  ARG     Pages:WORD                                            ¦
 ¦      mov     [emmError],0    ; Inicializa flag de erros...     ¦
 ¦      mov     bx,[Pages]      ; BX = número de páginas a alocar ¦
 ¦      mov     ah,43h                                            ¦
 ¦      int     67h             ; Invoca o EMM.                   ¦
 ¦      or      ah,ah           ; Verifica erro do EMM.           ¦
 ¦      jz      @@no_error                                        ¦
 ¦      mov     [emmError],ah   ; Poe erro na variável emmError   ¦
 ¦      mov     dx,-1                                             ¦
 ¦  @@no_error:                                                   ¦
 ¦      mov     ax,dx           ; retorna código de erro.         ¦
 ¦                              ; ou o handle.                    ¦
 ¦      ret                                                       ¦
 ¦  ENDP                                                          ¦
 ¦                                                                ¦
 ¦  ; Libera páginas alocadas.                                    ¦
 ¦  ; Protótipo em C:                                             ¦
 ¦  ;   void pascal emmFreePages(int handle);                     ¦
 ¦  ; Obs: Näo verifica erros... modifique se quiser...           ¦
 ¦  PROC    emmFreePages                                          ¦
 ¦  ARG     handle:WORD                                           ¦
 ¦      mov     dx,[handle]                                       ¦
 ¦      mov     ah,45h                                            ¦
 ¦      int     67h                                               ¦
 ¦      ret                                                       ¦
 ¦  ENDP                                                          ¦
 ¦                                                                ¦
 ¦  ; Mapeia uma página no Page Frame.                            ¦
 ¦  ; Protótipo em C:                                             ¦
 ¦  ;   int pascal emmMapPage(int handle,                         ¦
 ¦  ;                         unsigned char pfPage,               ¦
 ¦  ;                         unsignec PageNbr);                  ¦
 ¦  ; Onde: handle é o valor devolvido pela funçäo de alocaçäo de ¦
 ¦  ;       páginas.                                              ¦
 ¦  ;       pfPage é o número da página do Page Frame (0 até 3).  ¦
 ¦  ;       PageNbr  é o número da página a ser colocada no       ¦
 ¦  ;       Page Frame (0 até máximo - 1).                        ¦
 ¦  ; Devolve -1 se ocorreu erro e seta a variável emmError.      ¦
 ¦  PROC    emmMapPage                                            ¦
 ¦  ARG     handle:WORD, pfPage:BYTE, PageNbr:WORD                ¦
 ¦      mov     [emmError],0                                      ¦
 ¦      mov     ah,44h                                            ¦
 ¦      mov     al,[pfPage]                                       ¦
 ¦      mov     bx,[PageNbr]                                      ¦
 ¦      mov     dx,[handle]                                       ¦
 ¦      int     67h                                               ¦
 ¦      or      ah,ah                                             ¦
 ¦      jz      @@no_error                                        ¦
 ¦      mov     [emmError],ah                                     ¦
 ¦      mov     ah,-1                                             ¦
 ¦  @@no_error:                                                   ¦
 ¦      mov     al,ah                                             ¦
 ¦      ret                                                       ¦
 ¦  ENDP                                                          ¦
 ¦                                                                ¦
 ¦  ; Retorna com o erro do EMM.                                  ¦
 ¦  ; Protótipo:                                                  ¦
 ¦  ;   int pascal emmGetError(void);                             ¦
 ¦  PROC    emmGetError                                           ¦
 ¦      mov     ax,[emmError]                                     ¦
 ¦      ret                                                       ¦
 ¦  ENDP                                                          ¦
 ¦                                                                ¦
 ¦  END                                                           ¦
 +----------------------------------------------------------------+

    Esta  é  uma   implementaçäo   simplificada,   mas  para  nossos
propósitos serve muito bem.  Algumas consideraçöes:  A  alocaçäo  de
memória  via  EMM näo é feita da mesma maneira que a funçäo malloc()
de C ou GetMem() do  TURBO  PASCAL.  Näo é devolvido nenhum pointer.
Isto se torna óbvio a partir do momento que entendemos como funciona
o EMM: Toda a manipulaçäo de bancos de  memória  é  feita  de  forma
indireta pelo Page Frame.  A funçäo de alocaçäo deve apenas devolver
um handle para que possamos  manipular as páginas alocadas.  Entenda
esse handle da mesma forma com que os  arquivos  säo  manipulados...
Se  quisermos  usar um banco alocado precisamos informar ao EMM qual
dos bancos queremos usar, fazendo  isso  via o handle devolvido pelo
próprio EMM.

    Suponha que queiramos alocar  128kb  da memória expandida para o
nosso programa.  Precisamos alocar 8 páginas  lógicas  (8  *  16k  =
128k).  Chamariamos a funçäo emmAllocPages() em C da seguinte forma:

 +----------------------------------------------------------------+
 ¦  #include <conio.h>                                            ¦
 ¦  #include <stdlib.h>                                           ¦
 ¦                                                                ¦
 ¦  int emm_handle;                                               ¦
 ¦                                                                ¦
 ¦  void f(void)                                                  ¦
 ¦  {                                                             ¦
 ¦      /* ... */                                                 ¦
 ¦      if ((emm_handle = emmAllocPages(8)) == -1) {              ¦
 ¦          cprintf("EMM ERROR #%d\r\n", emmGetError());          ¦
 ¦          exit(1);                                              ¦
 ¦      }                                                         ¦
 ¦      /* ... */                                                 ¦
 ¦  }                                                             ¦
 +----------------------------------------------------------------+

    Na  funçäo  emmAllocPages() optei por devolver -1 para indicar o
insucesso da funçäo...  Você pode  arrumar um esquema diferente para
chegar isso (por  exemplo,  checando  a  variável  emmError  após  a
chamada a funçäo!).

    Well...  Temos 8 páginas lógicas disponíveis.  E agora?...  As 8
páginas estäo sempre numeradas de 0 até o máximo - 1.  No nosso caso
teremos as páginas 0 até 7 disponíveis ao nosso programa.  Lembre-se
que cada uma tem apenas 16k de tamanho e que podem ser arranjadas de
qq  maneira  q  vc  queira  no  Page Frame.  Vamos usar as 4 páginas
iniciais como  exemplo...  para  isso  precisamos  mapea-las no Page
Frame usando a funçäo emmMapPage().

 +-----------------------------------------------------------------+
 ¦  void f(void)                                                   ¦
 ¦  {                                                              ¦
 ¦      int i;                                                     ¦
 ¦                                                                 ¦
 ¦      /* ... */                                                  ¦
 ¦      for (i = 0; i < 4; i++)                                    ¦
 ¦          emmMapPage(emm_handle,i,i);                            ¦
 ¦  }                                                              ¦
 +-----------------------------------------------------------------+

    Depois  deste  pequeno  loop  sabemos  que qualquer alteraçäo no
conteúdo do  Page  Frame  alterará  as  páginas  que  estäo mapeadas
nele...:) Simples né?  Só nos resta conhecer o endereço  inicial  do
Page Frame:

 +-----------------------------------------------------------------+
 ¦  #include <dos.h>                                               ¦
 ¦                                                                 ¦
 ¦  void far *PageFrameAddr;                                       ¦
 ¦                                                                 ¦
 ¦  void f(void)                                                   ¦
 ¦  {                                                              ¦
 ¦      /* ... */                                                  ¦
 ¦      PageFrameAddr = MK_FP(emmGetPageFrameSegment(), 0);        ¦
 ¦      /* ... */                                                  ¦
 ¦  }                                                              ¦
 +-----------------------------------------------------------------+

    Ao  fim do uso da memória expandida precisamos dealocar o espaço
previamente alocado...  C  e  C++  dealocam automaticamente qualquer
espaço alocado por malloc(), calloc() e funçöes afins...   Näo  é  o
caso  de  nossas rotinas acima...  entäo acostume-se a manter a casa
em ordem e usar  a  funçäo  emmFree()  quando  näo precisar mais das
páginas alocadas.

    Isso  tudo  näo funcionará se o EMM näo estiver instalado...  No
texto anterior mostrei a rotina  para  determinar a presença do EMM.
E, no mesmo texto, apareceu a rotina emm_majorVer().  Eis  a  rotina
abaixo:

 +----------------------------------------------------------------+
 ¦  int emm_majorVer(void)                                        ¦
 ¦  { return ((int)emmGetVersion() >> 8); }                       ¦
 +----------------------------------------------------------------+

    See ya l8tr

Nenhum comentário:

Postar um comentário

Curso SANS 504 Hacker Techniques, Exploits & Incident Handling

SANS SECURITY 504 - Hacker Techniques, Exploits & Incident Handling     SANS Security 504.5.pdf13 MB     SANS Security 504.1.pdf12 M...