Menu
O mnie Kontakt

Jak zbudowane są pliki wykonywalne EXE? (Film, 11 minut)

Bisqwit w swoim najnowszym filmie zabiera widzów w fascynującą podróż do świata plików .exe oraz sposobu, w jaki komputery interpretują dane. Wiedza o tym, jak dokładnie komputer przetwarza i interpretuje liczby, może być zdumiewająca. Gdy otwierasz plik .exe w edytorze tekstu, dostrzegasz jedynie chaotyczny zlepek symboli – to tylko iluzja. Wewnątrz komputera nie ma nic poza liczbami, a każda litera czy znak to tylko reprezentacja tych liczb. Na przykład, 65 oznacza wielką literę A według standardu ASCII, który jest umową używaną od lat do interpretacji znaków. To prowadzi nas do zrozumienia, że każde otwarcie pliku .exe w edytorze tekstu zmusza do niewłaściwej interpretacji tych liczb jako tekst.

W filmie Bisqwita, widzowie dowiadują się, że pliki .exe są strukturami składającymi się z różnych sekcji, które system operacyjny identyfikuje, aby je przetwarzać w różny sposób. Autor koncentruje się na kodzie programu zawartym w tych plikach. Zawiera on różne rodzaje treści, a widzowie mogą zauważyć, iż nawet w pliku .exe znajdują się fragmenty tekstu, których znaczenie może być odczytane za pomocą edytora szesnastkowego. W tym dziele Bisqwit rozdziela dane na wersję zrozumiałą dla komputera, gdzie każda liczba w kontekście kodu maszynowego ma swoje specyficzne znaczenie.

Chociaż interpretacja liczb może wydawać się zawiła, z filmu wynika, że każda sekwencja liczb prowadzi do konkretnych instrukcji assemblera. I tak, gdy widzimy ciąg 4883EC48, reprezentuje on instrukcję, która odejmuje liczbę od rejestru RSP w architekturze 64-bitowej AMD64. Autor wyjaśnia również, co to oznacza w odniesieniu do szerszego kontekstu programowania, przytaczając dokumentację, która wyjaśnia zasady działania procesora.

Bisqwit podąża za przykładem procesora 8086, pokazując różnice między współczesnymi i przestarzałymi architekturami. Umożliwia to widzom zauważyć, jak rozwijała się technologia komputerowa przez ostatnie cztery dekady. Legalizowanie starej dokumentacji procesora jako pomoc do zrozumienia nowoczesnych systemów jest niezwykle ciekawe. Co więcej, autor demonstruje, jak każdy bajt instrukcji programu jest ze sobą połączony, a informacje są zapisane w strukturze, którą przy pomocy tabelki można zinterpretować.

Warto także zaznaczyć, że w momencie pisania tego artykułu film Bisqwita zgromadził już 148 447 wyświetleń i 9 941 polubień. To pokazuje znaczenie i zainteresowanie omawianymi przez niego tematami, które mogą otworzyć oczy na tajemnice technologii komputerowej. Warto zapoznać się z jego twórczością, aby odkryć więcej podobnych istotnych zagadnień dotyczących programowania i architektur komputerowych. Pełen zasobów film niewątpliwie dostarczy wiedzy i zainspiruje do dalszego poznawania tej skomplikowanej dziedziny.

Toggle timeline summary

  • 00:00 Wprowadzenie do otwierania pliku .exe w edytorze tekstu.
  • 00:10 Wizualna reprezentacja pliku .exe wygląda jak bałagan.
  • 00:22 Dyskusja na temat tego, że komputery rozumieją tylko liczby.
  • 00:38 Wyjaśnienie ASCII jako standardu reprezentacji znaków.
  • 01:04 Otwieranie pliku .exe w edytorze tekstu przypisuje interpretację jego danym.
  • 01:20 Jeśli otworzony w odtwarzaczu audio, plik widziany jest jako próbki PCM.
  • 01:35 Otwieranie pliku w przeglądarki obrazów ujawnia liczby interpretowane jako kolory.
  • 01:50 Używanie edytora heksadecymalnego do przeglądania surowych liczb wewnątrz pliku .exe.
  • 02:03 Plik .exe zawiera zarówno kod binarny, jak i tekst czytelny.
  • 02:26 Wyjaśnienie, że pliki .exe są strukturami zawierającymi różne typy zawartości.
  • 02:40 Wizualizacja deasemblacji pliku .exe.
  • 03:20 Zrozumienie instrukcji asemblera na podstawie sekwencji liczb.
  • 04:08 Krótka historia architektury CPU od 8086 do AMD64.
  • 06:15 Porównanie deasemblacji z kartą danych CPU 8086.
  • 08:00 Kodowanie instrukcji i jak jest to odzwierciedlone w karcie danych.
  • 08:46 Ilustracja, jak liczby w instrukcji odpowiadają operacjom.
  • 10:40 Złożone zadania są realizowane poprzez sekwencje małych instrukcji.
  • 10:45 Zakończenie od Bisqwita zapraszające do dalszego zgłębiania tematów.

Transcription

At least once, at some point in your life, you may have tried to open an .exe file in a text editor – just to see what happens, and it looks like this. It's a total mess. How does a computer make sense of any of this? The thing is, what you see on the screen is an illusion. It does not exist. Everything the computer ever sees and deals with is numbers. On a computer, there is nothing else but numbers. Anything else is a representation. There are agreed-upon standards – describing which numbers are used to represent which letters, so that we can handle text on a computer. There is really no text, only numbers. But we have agreed a long time ago – that 65 means capital A, 70 means capital F, and so on. This agreement is called ASCII, American Standard Code for Information Interchange. Later it was extended and updated, but that's another topic. When you tell your text editor to open an .exe file, you are assigning an interpretation to the number sequence. By opening the file in a text editor, you insist that these numbers should be interpreted as text. But they are not text. If you opened this file in an audio player, they would be interpreted as PCM samples, and you could listen to the sound made from these numbers. It usually does not sound very pleasant. But the file is not audio either. You could open it in a picture viewer, and it would look like this. Now the picture viewer is interpreting the numbers as colors, but the numbers are not colors either. We can use a hex editor to look at the numbers inside the file, and see the numbers as what they really are. Numbers. What do the numbers mean then? Answering that question is not exactly straightforward. If you look carefully, you can actually see that this .exe file does actually contain some text. I mean, it still contains numbers, but these particular numbers here actually make sense, even if they are interpreted as text, as my hex editor helpfully does. You may have thought of .exe files as buckets of computer code. A monoculture of an abstract thing called code. But that is wrong. They are actually structures. This file contains many kinds of content, and the operating system identifies these sections, and handles them differently. For now, we will focus on just the program code. This is a disassembly of an .exe file. All disassemblies look something like this. On the left edge, you see an address. It might be a memory address, or an offset to a file. In this case, it is a memory address. The second column is those numbers from the file. If I open side-by-side this disassembly, and the hex editor view, you can see how these contents are related. The code begins here. Here's the first four bytes, then the next four bytes, then two bytes and seven bytes, and so on. They are a perfect match, because it is the same data. The third column is assembler instructions. And this is the most mystifying part for many people. Remember earlier when I said that – when the numbers are interpreted as text, 65 means A. When the numbers are interpreted as program code, this is the interpretation. The number sequence 4883EC48 – means the assembler instruction – that subtracts this number from RSP. The number sequence 4C8D4210 – means the assembler instruction – that adds one to RDX and stores it into R8. The number sequence 8BCA – means the assembler instruction that copies EDX into ECX. But why? Also you will notice that these number sequences – have different lengths. How does it work? This is a modern day 64-bit architecture called AMD64. The AMD64 architecture programmer's manual – is six volumes long, almost 3000 pages in total. For simplicity, we'll take a look at the 8086 CPU datasheet instead. It is only 30 pages long. The 8086 is the CPU inside this computer. It is an ancestor of AMD64, released over 40 years ago. Actually, let's take a moment to appreciate the sounds of this beauty. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 We can even have a look at this assembly. Here's one. Even though instructions look quite similar – as in the previous sample, that is not a coincidence. These two processors are related after all. In this 30-page manual, the interesting bits begin at page 26. Know what? Let's do a side-by-side view. On the left side, the disassembler listing. On the right side, the datasheet. So the first instruction is 8CC8. Move the code segment register into the AX register. Can we find it in the datasheet? As luck would have it, we can actually find it on this very page. It's here. The instruction is MOVE, and the order of operation is – segment register into register or memory. If we then look at the right side of the page, we see this chart. This chart tells that this particular instruction – is encoded using two bytes. The bytes are described in binary, not hexadecimal, so the description goes 10001100. This is 8C in hexadecimal. And it matches exactly what we see in the disassembly. The second byte is something called MODRM. We will get back to that later. Now let's scroll down the disassembly a bit. How about this one? LODSB. That's byte AC, or 10101100 in binary. In the datasheet we can find this instruction on page 28. Here it is. LODS. The instruction encoding is 1010110W, where W denotes the size. Zero for byte size, and one for word size. This instruction had a zero here, so it is LODSB. Load String Byte. The next instruction is 49. This is 01001001 in binary. Can we find it in the datasheet? Indeed we can. Here it is on page 27. The first byte is 01001, and then something called REG. The instruction is called DEC or decrement. Our byte ended with 001, so what does the REG number of 001 mean? The answer is found on the last page, page 30, in this table. REG is assigned according to the following table. 001 means CX. So our instruction was DECCX. Did we interpret it correctly? Let's have a look. Oh yes. The instruction was DECCX indeed. On this page in the datasheet, it also describes how that mod RM from earlier works. I'll leave that as an exercise to the reader. Inside the microprocessor there is a lookup table. The processor reads the number from the program, and compares that number into this lookup table. Suppose it finds the number 11000011. It reads this table, and finds that this is RET, the subroutine return instruction. It therefore performs that operation. Then it reads the next number. Suppose that the next number it finds is 11101001. This is the unconditional jump instruction, but look, it needs more data. It needs to read two more numbers. The instruction is three bytes long. The two other numbers together constitute a bigger number, that tells where it should jump next. Once it has read three bytes, it now has enough information to perform the operation, which it will promptly do. And then it reads the next number. That's what the processor does for all eternity. Millions or billions times in a second. Read an instruction, interpret it, execute it, and do that same over and over and over again. Some of these instructions might be complex – and require multiple bytes, others are short and only one or two bytes long. There are other processor architectures – in which instructions are always same width, but on the x86 architecture, instructions have varying lengths. And that's how the numbers in your .exe file map into program code. That program code just happens to consist of – millions of tiny instructions that do very small things. But when millions of them are performed in a sequence, in a rapid fashion, something more complex is achieved, such as the computer reacting to your mouse button click. I am Bisqwit. I do videos about topics – that I hope are just as insightful and inspiring to you – as they were to me when I originally learned the stuff. Have a blessed day, and see you again!