Asembler - dlaczego tyle zer w tym prostym kodzie

0

Od paru dni zamierzam tak dla własnej przyjemności poznać przynajmniej podstawy asemblera. Nie posiadam jeszcze żadnej książki ale mam i przeczytałem kurs P. Drozdowskiego (chociaż dla DOSa) i czytam obecnie kurs Iczeliona. Wybrałem i korzystam z FASMa (dużo powodów, których nie będę wymieniał).
Na stronie forum FASMa w wątku o programie HelloWorld (bo jakżeby inaczej - od tego trzeba zacząć) jeden z forumowiczów podał taki kod (wybrałem ten, bo moim środowiskiem jest też Win7 64-bit):

; Example of 64-bit PE program

format PE64 GUI
entry start

section '.text' code readable executable

   start:
      sub     rsp,8*5         ; reserve stack for API use and make stack dqword aligned

      mov     r9d,0
      lea     r8,[_caption]
      lea     rdx,[_message]
      mov     rcx,0
      call    [MessageBoxA]

      mov     ecx,eax
      call    [ExitProcess]

section '.data' data readable writeable

   _caption db 'Win64 assembly program',0
   _message db 'Hello World!',0

section '.idata' import data readable writeable

   dd 0,0,0,RVA kernel_name,RVA kernel_table
   dd 0,0,0,RVA user_name,RVA user_table
   dd 0,0,0,0,0

   kernel_table:
      ExitProcess dq RVA _ExitProcess
      dq 0
   user_table:
      MessageBoxA dq RVA _MessageBoxA
      dq 0

   kernel_name db 'KERNEL32.DLL',0
   user_name db 'USER32.DLL',0

   _ExitProcess dw 0
      db 'ExitProcess',0
   _MessageBoxA dw 0
      db 'MessageBoxA',0

Moje pytanie dotyczy trzech linii:

dd 0,0,0,RVA kernel_name,RVA kernel_table
dd 0,0,0,RVA user_name,RVA user_table
dd 0,0,0,0,0

Chodzi o te zera. Dlaczego jest ich aż tyle i jeszcze dodatkowo 5 zer na końcu? To nie jest wytłumaczone ani w kursie P. Drozdowskiego ani w kursie Iczeliona. Proszę o pomoc. I to prostym językiem. Ja asemblera się dopiero uczę.

PS. wiem że można program HelloWorld w asmie napisać szybciej i kod będzie krótszy stosując includy, które są w katalogu po rozpakowaniu FASMa ale nie chcę na razie z nich korzystać bo choć skrócą mi kod to i tak nie będę wiedział dlaczego mi go skracają nie znając specyfiki samego FASMa i asemblera.

1

Cała sekcja .idata wygląda na jakieś ręczne budowanie sekcji importów w pliku PE.

Część o którą pytasz (ta z zerami) to import directory table. To "tablica" zawierająca trzy elementy. W pseudostrukturze:

struct idt_entry {
    union {
        uint32_t characteristics;
        uint32_t first_thunk; // to chyba nie powinno być zerem, ale widać jest
    } // unia = jedno pole pod dwoma nazwami.
    uint32_t timestamp; // opcjonalne, u Ciebie zera
    uint32_t forwarder_chain;
    uint32_t name_rva; // rva do nazwy dll
    uint32_t first_thunk_rva; // rva do listy thunków, tzn, poszczególnych importowanych funkcji
}

Niżej jeszcze dwie struktury ale nie będę już dokładnie opisywał -> więcej informacji na pewno w dokumentacji PE albo szukając za import address table/import directory table.

Nie jestem pewien czemu ten kod buduje tą strukturę ręcznie (może to jakaś demonstracja że można? i tak linker musi wiedzieć co to jest) - zazwyczaj równie dobrze może to zrobić sam asembler.

0

Dziękuję za odpowiedź

msm napisał(a):

Nie jestem pewien czemu ten kod buduje tą strukturę ręcznie (może to jakaś demonstracja że można? i tak linker musi wiedzieć co to jest) - zazwyczaj równie dobrze może to zrobić sam asembler.

Jeżeli może to zrobić sam asembler to czy mógłbyś podać taki skrócony kod? Wystarczy, że będzie wyświetlał napis "HelloWorld" w konsoli (dla Win64, kompilator FASM). Na początek chcę opanować sam dialekt procesora. Okienkami zajmę się gdy opanuję podstawy asemblera.

Jeszcze raz dziękuję za odpowiedź

0
section '.idata' import data readable writeable 
library user32, 'user32.dll' , \
        kernel32, 'kernel32.dll'

import user32, MessageBoxA, 'MessageBoxA'
import kernel32, ExitProcess, 'ExitProcess'

nie sprawdzane.

1 użytkowników online, w tym zalogowanych: 0, gości: 1