We're sorry but this page doesn't work properly without JavaScript enabled. Please enable it to continue.
Feedback
00:00

Formal Metadata

Title
GNU poke
Subtitle
The extensible editor for structured binary data
Title of Series
Number of Parts
542
Author
License
CC Attribution 2.0 Belgium:
You are free to use, adapt and copy, distribute and transmit the work or content in adapted or unchanged form for any legal purpose as long as the work is attributed to the author in the manner specified by the author or licensor.
Identifiers
Publisher
Release Date
Language

Content Metadata

Subject Area
Genre
Abstract
GNU poke is an interactive, extensible editor for binary data. Not limited to editing basic entities such as bits and bytes, it provides a full-fledged procedural, interactive programming language designed to describe data structures and to operate on them. In this activity we will show the program and discuss about the current status of the project.
14
15
43
87
Thumbnail
26:29
146
Thumbnail
18:05
199
207
Thumbnail
22:17
264
278
Thumbnail
30:52
293
Thumbnail
15:53
341
Thumbnail
31:01
354
359
410
Text editorContent (media)Lattice (order)Entropie <Informationstheorie>String (computer science)Core dumpASCIIView (database)Binary codeData structureMP3Declarative programmingCodeInteractive televisionElectric generatorTexture mappingData integrityPOKEProblemorientierte ProgrammierspracheType theoryFunction (mathematics)Variable (mathematics)Maß <Mathematik>Data centerRight angleNeuroinformatikDegree (graph theory)Flow separationArmAreaCASE <Informatik>BitLibrary (computing)Computer programmingHypermediaState of matterRepresentation (politics)Group actionComputer fileTouchscreenSystem callBinary codeString (computer science)1 (number)Term (mathematics)Position operatorText editorView (database)Beat (acoustics)Traffic reportingMereologyContent (media)Level (video gaming)Bus (computing)Goodness of fitNumberAbstractionExtension (kinesiology)WritingData structureMathematicsUniform resource locatorSheaf (mathematics)POKEProjective planeDigital photographyNetwork topologyMeasurementPattern languageCore dumpParsingCodeMP3CompilerInternetworkingProgramming languageVariety (linguistics)Frame problemFile formatElectronic mailing listMetadataProgramming paradigmDeclarative programmingParsingElectric generatorQuicksortDiagramComputer animation
Type theoryFunction (mathematics)Variable (mathematics)Texture mappingData integrityInteractive televisionData structurePOKEProblemorientierte ProgrammierspracheText editorMaß <Mathematik>Reverse engineeringFile formatCommunications protocolPrototypeBinary codeDigital filterFunctional programmingDisintegrationComputer programAddress spaceSpacetimeAbstractionObject-oriented programmingIntegerSequenceString (computer science)Computer fileError messageStreaming mediaStandard deviationoutputClient (computing)Read-only memoryBuffer solutionNegative BinomialverteilungServer (computing)Process (computing)ComputerRange (statistics)QuantumComputer programmingSemiconductor memoryFile formatExecution unitBitCommunications protocolINTEGRALDifferent (Kate Ryan album)NumberProgramming languageComputer hardwareProcess (computing)Address spaceIntegerSpacetimePOKERange (statistics)Text editorWordParsingData integrityCASE <Informatik>Hand fanProblemorientierte ProgrammierspracheCartesian coordinate systemSinc functionDevice driverSpeicherbereinigungNeuroinformatikFlow separationComputer fileWritingTextsystemTask (computing)Moment (mathematics)Shift operatoroutputLibrary (computing)Term (mathematics)InternetworkingData structureRevision controlRight angleDisk read-and-write headFocus (optics)Point (geometry)Reading (process)Constraint (mathematics)View (database)Utility softwareAreaFunctional programmingPlanningPrototypeShared memoryLine (geometry)Multiplication signMereologyBeat (acoustics)Scaling (geometry)InformationFilm editingReverse engineeringObject-oriented programmingSystem callProgrammable read-only memoryLevel (video gaming)Type theoryCompilerCombinational logicCovering space1 (number)Traffic reporting
SphereEstimationRead-only memoryOracleComa BerenicesCore dumpBinary fileComputer fileCartesian coordinate systemLogische ProgrammierspracheDemo (music)Context awarenessObject-oriented programmingComputer animation
SphereProcess (computing)DisintegrationDebuggerCartesian coordinate systemSemiconductor memoryProcess (computing)Branch (computer science)Combinational logicComputer programmingDemonDemo (music)Problemorientierte ProgrammierspracheFile formatExtension (kinesiology)CodeAsynchronous Transfer ModePoint (geometry)Utility softwareMoment (mathematics)Multiplication signInterface (computing)Execution unitPOKESoftware bugComputer animation
Maxima and minimaGame theoryEmailSigma-algebraWorld Wide Web ConsortiumScalable Coherent InterfaceComputer fileComputer wormType theoryBuffer solutionSemiconductor memoryInterior (topology)Address spaceCartesian coordinate systemVariable (mathematics)File formatComputer programmingControl flowSymbol tableQuicksortDatabaseData structureRouter (computing)Context awarenessProcess (computing)Point (geometry)Structural loadRight angleMultiplication signFocus (optics)Token ringGoodness of fitCASE <Informatik>Graphics tabletFerry Corsten40 (number)View (database)
Electric currentDisintegrationAssembly languageSoftware maintenanceAsynchronous Transfer ModeElectronic mailing listHacker (term)Continuous integrationSource codeRepository (publishing)WebsitePole (complex analysis)Text editorBinary fileTable (information)Data structurePoint (geometry)Pointer (computer programming)Graphics tabletSparse matrixElectronic mailing listINTEGRALAssembly languageData structureWorkstation <Musikinstrument>TheoryCartesian coordinate systemElement (mathematics)Video gameQuicksortComputer programmingSoftware maintenanceSoftware developerProcess (computing)Plane (geometry)DemosceneToken ringContext awarenessPoint (geometry)Stability theoryPlotterRight angleDifferent (Kate Ryan album)Branch (computer science)Repository (publishing)WebsitePlanningInformationComputer clusterArmNoise (electronics)Goodness of fitEmailProjective planeLine (geometry)Dot productSoftware testingSampling (statistics)MereologyUniverse (mathematics)NeuroinformatikDifferenz <Mathematik>Direction (geometry)RobotReal numberSheaf (mathematics)POKESparse matrixBlogSymbol tableSource codeTable (information)Patch (Unix)Pairwise comparisonExecution unit
Arrow of timeGEDCOMDialectHacker (term)Directory servicePOKERevision control
Image warpingStandard deviationInformationCore dumpArchitectureExtension (kinesiology)Source codeCloningSheaf (mathematics)EmailOnline helpTraffic reportingRevision controlInstallation artEuclidean vectorComputer fileUniversal product codeCovering spaceSystem callFrame problemNetwork topologyRegulärer Ausdruck <Textverarbeitung>Repository (publishing)CASE <Informatik>Monster group
Finite element methodFingerprintAsynchronous Transfer ModeDisk read-and-write headDirac equationHost Identity ProtocolHacker (term)InformationComputer programPOKEGroup actionSource code
Source codeInformationRight angleRevision controlWeb pageQuicksortPOKEMetropolitan area network
Line (geometry)Mach's principleLattice (order)Network topologySource codeCanonical ensembleSampling (statistics)Complex (psychology)Goodness of fitInternetworkingComputer programmingVideoconferencingSoftware developerMultiplication signForm (programming)Information
Program flowchart
Transcript: English(auto-generated)
All right. So it's two minutes early, but I have a tendency to speak and not stop, so we better get started here. So I am so tired of doing introductory talks to poke.
So I have decided that this is the last one I'm going to do. But let's see. Is anyone here familiar with this program somehow? Yes? OK. So yeah, we need to do an introductory talk. So GnuPoke is an extensible editor
for structured binary data. So it is a program that you can actually expand. We will see how. And you can expand it actually quite to a very high degree. And we will see that it's a program that is used to poke or to mess, to edit data which
is encoded in binary. We will see what is this thing about binary. Everything is binary at the end of the day, right? So first, I'm going to do a very small introduction, an abstract one. I mean, why would you use such a program? Then we will see how we are actually integrating poke in other programs via a shared
object, a library. Then I will basically talk a little bit about the project itself, the current status. We just made a major release that we are very happy about it. And we are very busy because we have a lot of things to do. It's getting very fun actually. And then finally, an invitation
to you to actually join us in hacking this program. So let's start with a very small introduction. I mean, when it comes to edit binary data, well, what do you use? You use a binary editor, right?
If you go around and then you look around in internet about binary editors, you have the simplest kind, what I call simple binary editors, which is your garden variety programs which show you a byte dump.
And then a lot of them also show you the ASCII representation of the same bytes. What do you see in the screen? How many of those programs are around? Quite a lot of them. And they are nice. I mean, they are nice, they are useful, they are small, they are very easy to use. There is nothing mysterious about them.
They are interactive, usually. The ones that allow you to actually change the value of those bytes in the files, you just go to the byte you want to change, you put in the new value for the bytes, ta-da. If you want to change based on some string, you go to the ASCII column there, you go to the position you want to edit, you change it,
but you know the file gets updated. Very nice. They are interactive. They support immediate editing. Like you go, you change here, and it immediately gets reflected in the file that you are editing, for example. What do they let you edit? In terms of what? Well, it depends. But those simple binary editors, they let you operate in terms of bytes, in terms of strings,
like we just mentioned. And sometimes, this is not often, but sometimes in terms of bits as well. Some of those basic binary editors, they support down to the bit level too. And that's it.
That's the thing. You can edit in terms of those entities, of those concepts, bytes, bits, strings sometimes, sometimes numbers. Then the editor is not so simple anymore. But it's always like a fixed list of abstractions that you can edit. You manipulate your data using those abstractions.
And then they give you, generally, byte dumps, the ASCII views. And they have fixed capabilities, depending on how nice the particular editor is. Some of them allow you to search for patterns. Some others allow you to search and replace, to make byte diffs, that kind of things. Measure entropy, to search for frame buffers,
that kind of things, right? Simple binary editors. They are useful. But then sometimes, you have to edit, or you want to edit your data in terms not just of bytes or bits, but in terms of more abstract entities, like MP3 headers,
or ELF relocations, or lists of numbers, or whatever. And then for that, you have traditionally specialized binary editors, which are editors, like the two that you can see here, that know about some particular format,
like some of them. The one on the left knows about the ELF format. So you can see a three view, which is quite nice, you know, with the different sections in the ELF. And the one on the right, which is small, but it's nice, is a very small MP3 editor to edit MP3 files. Actually, the metadata is treated with the MP3, like the title of the song, the name of the singer,
or whatever, right? Those specialized binary editors, they are nice, too. They are useful. But they are not extensible, usually. I mean, you cannot go and say, oh, well, you know, I mean, in the ELF program here, you know that ELF sections can contain arbitrary data, right?
So you say, well, I want to use the same editor to edit the contents of one of the ELF sections. Now, usually, they don't let you do that. So they are not extensible. They also, they are not quite good at dealing with incorrect data. So if you get a corrupted ELF file, or some MP3 file that
has problems in it, those editors probably, they are going to refuse to actually open them, open those files. And if they do, they are probably going to show you garbage, right? So they are not good at that. And you know it's the typical situation. Exactly what you need is what they don't implement, right?
It's always like that. So those are the specialized binary editors. And then we have KTAIS struct and friends, which is they implement this paradigm of, as you know, we got a nice presentation before. The first, you decode the data, like with one of the parsers of KTAIS struct, for example.
Then you do your computation with the data. And then maybe you use an encoder to write back the modified data. This is what I call decode-compute-encode. Programs like these are also useful. Those are extensible, like we have seen with KTAIS struct. You can define your own structures.
They use, usually, some sort of declarative way of describing the layout of those data structures. They generate code in several target languages. I don't know why KTAIS struct does not generate C. I mean, to me, I'm so puzzled about that, but okay.
Usually, those are non-interactive. They are not interactive. Like you generate a parser that generates, you know, that parser in some programming language that then you incorporate in your program and then you run, right? Usually, they are not that good to dealing with incorrect data either, right?
Because the parser that they generate expects correct data. And they are either bit-oriented, which is not common. I don't know if KTAIS struct can deal at the bit level. Good. Also, not-aligned stuff. And, or bit-oriented.
And often, there are no encoders. I know that the KTAIS struct now, they are starting to add the support for actually writing data back to the file. This is nice, too. And then you have the poke approach, which is circular.
What we wanted with this was the following. We wanted the immediate aspect of the simple binary editors. Like, okay, I go to this byte and then I change it. Now, you know, I mean, now change it immediately. But also, we wanted the extensibility and the ability of working with higher abstractions like you have, you know, with the parser generators,
like KTAIS struct, for example. We wanted everything together. And that is what poke is, you know, in few words. Basically, you describe your data structures, like in a struct type, for example, and you can immediately poke at it. You can immediately update it, edit it, write to it.
And if you are not satisfied with that, you can, on the fly, using the same program in the prompt, you can redefine your data structure, right? And do it again. This is good for also discovering, you know, the format of what you are editing, like in reverse engineering and whatnot. And when you are developing a new format,
you know, that kind of use cases. So it is interactive with the poke application. It allows immediate editing. It allows data integrity. You can define your own complex structure, quite complex ones. And then it supports a very powerful and to the point domain-specific language.
I'm a big fan of domain-specific languages because we have the ability and the brains to actually, you know, talk in several languages and write in several programming languages. And it is so great when a tool actually gives you, you know, the way of expressing things that are most suitable for the task at hand. The DSL is called poke as well, like the program,
but with a big P to distinguish the programming language from the program itself. It is interactive, aesthetically typed, in purpose. It is garbage collected. It has some very interesting features, this programming language, because it's designed to, you know, to the point, to the task at hand.
So for example, it's not bit-oriented and it's not byte-oriented. It is unit-oriented. So in poke, when you start talking about offset sizes in memory and so on, you don't talk in bytes or in bits. You talk in terms of arbitrary units that you can define. Right? I'm sorry I cannot go into detail
because this is, you know, like a fast pitch, but you have all the information, you know, in internet and so on. And also it works in bit-addressable IOS spaces. It can work with incorrect data because you can do non-strict mapping, saying, okay, I want to disable the constraints, the integrity constraints, so you can actually discover what you have in front of you
and adapt your own definitions to it, and so on. You can define several versions of the same structure very easily to be more strict, less strict. And it is extensible. We will see that Nukemoke is not just a binary editor. It is a full infrastructure to write binary utilities as well, right?
And then, similarly to what Kaita is trying to do, for example, when it comes to document formats, you can use POC also to document formats and protocols in a functional way because your same documentation, you can use it, you know, to actually operate with the data.
To do prototyping, to write binary utilities, to implement filters, and so on. And then to integrate in other programs, which is very cool. I will show you in five minutes one example with the debugger, with GDB. Now, POC operates in, it can operate on files,
memory buffers, you know, the memory of running processes. There is a collection of IO devices, right, which are what you are editing. But what a POC program or what you have access from the command line is to a bit addressable IO space. We call those IO spaces, in which you can actually map
or, you know, manipulate different kind of entities, which are integers, and same integers are strings, right? From the POC language. Okay, we all know what bytes are, right? You will be surprised, many people don't. They are just little numbers in a certain range, right?
From zero to 255. So this is the way, you know, in POC you have to refer to bytes. But what I wanted to show you, because I think it's the interesting part, is that it's the way that you go, that in POC you have from going from bytes to actually encoding integers, right?
So you see here, I don't know if you can see, you see here the IO device there, which is the underlying device that you are editing, like the file, right? And then it has bytes, which are little numbers, right? From zero to 255 in the range. And then the IO space, which is on top of each byte,
of the bytes, is the bit addressable IO space that your POC programs actually see. But we all know that bits, it's actually a very interesting thing. Bits exist, usually, at the hardware level, then they disappear, until you will recreate them, you know, virtually, you know,
on top of those byte numbers, right? It's very interesting. But, so, from POC what you see is the bits, you know, that are conceptually on top of the bytes. And that's the POC type, for example. This is a very, it's an unsigned 16-bit integer mapped in the IO device at the first byte.
But this is a boring example, it gets even more interesting. Like what we call wired integers, weird integers, right? So for example, in POC you can operate with 12 bits unsigned integers, as naturally as you would do with a 32-bit unsigned integer. This is quite cool, actually, and useful, believe it or not.
Then we have some conventions, you know, to refer to the bits and everything. But this integer actually occupies one full byte and then half of the next one. But also you can go to less than one byte, right?
Like in this case. So you can actually operate with an unsigned integer of five bits. And then it doesn't feel, you know, a complete byte. Obviously, since everything that there is in a computer is actually bytes, the drivers level, hardware level, you know, and everywhere, this is an artifact, but it's a useful one.
And POC also has full support for unaligned stuff too, right? So you can work with actually a 16-uncined integer, shift to bits in the IO space. Can KITA extract do that?
Yes? We will have to see. So yeah, so you could obfuscate your file just by shifting that three bits to the right, for example, why not? Maybe fun. I just included this here not to impress the cat,
but to give you an impression, you know, the impression that actually POC, it's a serious program. I mean, it's not just, you know, a stupid program, you know, that poking at bytes here and there. We actually take it very seriously. And you can do this kind of stuff. And believe it or not, people need this kind of stuff. The other day in the IRC, we met the Multicians, which is a community of people who are,
you know, dealing with Multics. And you will not believe what they need. Really, right? I mean, like nine bits bytes, you know how it's unbelievable. And we are struggling to actually give the people what they need because they have rights too. The Multics people have rights too.
Anyway, so the POCosphere, POC is growing and growing. This started with one simple, it was always a little bit special, but you know, a little program, but it's getting out of hands at the moment. And in the sense that we have libpoc,
which is a shared object. Obviously, first I made it in a problem, but the dotty in one column, you are an asshole. Put it in a library, so I did. So, and then libpoc is a shared object that has the POC incremental compiler, the IOS space support and everything. We will see now with GDB as an example,
how you can actually make use of it in your own programs. Then POC is the command line application, right? Which uses libpoc. But it's just a program, a very small program, you know, with a prompt, you know, like bin ls, load, elf, you can dump bytes, right?
Oops, sorry, here. And bar elf, elf 64, five, zero bytes, you know. Stuff like this. The command line application. But all of the logic is actually in the shared object. Then you have other applications like GDB,
which have, this is not upstream yet, it's in a branch upstream, but not in master. But they can actually use libpoc to give you POC capabilities. I will show you now in a two minute little demo. There is a POC daemon too, that Mohamed will talk about. Yeah, I have 10 minutes. Utilities, the pickles, which are the POC programs
that give you the support for some particular format or some particular domain. Then there is an MX interface, of course. Then there is an MX mode for the POC program, VIM for unholy people, for anything, you know, the POC code in VIM, in VI.
Something called POClets, and so on, and so on, and so on. So it's getting fun. And then the integration. I'm very, I like this, you know? You know, there is one problem, when people write a problem, they want it to do everything very well, right?
And that does not work. So for example, in POC we have some support for editing the memory of running processes. We do, we do. Well, I could show you, but I don't have time for that. Because we have an IOD, which is, you can specify the process ID of a process, and then you can edit the running memory, you know, of the memory of the running process.
But POC is not a debugger, it's not. I mean, it doesn't, there is a door pickle, but you know, not to the same extent as a debugger. You cannot set breakpoints, you cannot, you cannot use ptrace to command a process. But GDB is a debugger. So GDB is good at debugging,
at running processes and so on. And POC is good at poking at data, right? So let's put them together. So then the combination is good at both. And this can be achieved by using leaf POC. So I can show you very fast.
So I have the C file, you see the C file? I have a C extract from, with an int tag. Can you see it properly there, or? Yes? Which one? Which one? No, I'm not gonna address this. Trust me. Okay, so there is this extract type,
then there is this buffer, there is this DB global variable here, and so on and so on, right? And an int main, int main, main. So then, I compile that into an IOD, and then I do home, this is the POC-capable GDB,
a.out, break main, run. Now I am in main, right? Here. And then I can use GDB to look at the database here, you know, this DB global variable and so on. Now, this GDB is extended with POC. So you have a POC command where you can execute any POC code,
like this, like two plus two equal four. Brilliant. But, here you can do anything that you can do with POC. So for example, you could say, and POC, in this case, it has access to the memory of the inferior that you are debugging with GDB. So even if it's multi-process or multi-thread,
you switch in GDB, and then POC has access to the memory of the inferior, right? So what kind of things you can do? Well, anything, I mean, what is the address in GDB of this global variable here?
That is the address, right? So with POC, you could access to that address. But, you have a command which is POC at types, right? Which is, you are telling GDB to make POC aware of all the types known to GDB at this point in time, right?
So the type char, the char type int, the struct prop that we saw before, and then this translated into POC type definitions for the equivalent GDB types. This means that you can go from BTF, from CTF, from DOR, from any debugging format that GDB understands to POC types, while you are using GDB in this way.
Now, POC now has access to the memory of the inferior. So, we could do, for example, and those are POC expressions, right? A struct prop at, at where? And you can use something we call alien tokens, which is the address of the GDB symbol DB,
which is the variable, right? And this is the POC struct. This is not a GDB value. This is a POC struct, which is POC in an inferior memory. And you, of course, can write, you can do whatever you want. You can load pickles. Why is this useful for? Well, imagine you are debugging a program
that is some sort of router for TCP. So the program itself, you know, you have TCP packets and some buffers in the program, but the program itself doesn't need to understand the payload of what it is transporting. But imagine that you want to take a look at what is going on there, right? So then, you don't have the DOR definitions
of the structures that are in the buffer, in the payload. But with POC, you just load your pickle, or you write your own, and you can POC at it from GDB in the buffer of the running process, for example, right? So this is one example of application. This is 400 lines of C, the integration, using lead POC.
It's very nice, and you know it's easy. Another example, which is work in progress, and I can't wait to get this finished, is basically to add to the assembler a dot POC directive. Because you know those dot word, dot byte,
and so on directives in the assembler? They are not portable. And this is a pain in the ass, because when you have to actually, for example, test DOR for test, you know, that kind of things, then they are not portable. I know it's amazing, but they are not portable. So see, for example, that.
This is a real example of something I found. I will not tell where. Of some people who are actually embedding some sort of executables inside other sections of some of the stuff. This is Sony computer. This is video games, you know? Kids, they do these kind of things.
And that is a struct, in theory, of what? Of some header, right? For the PlayStation or whatever. Well, compare. You see? So once we have the integration in the assembler, then you will be able to load the PSXX pickle.
It will be a small one where you define the structure of this executable. And then you could poke at assembly time like that, too. And accessing gas assembler symbols using alien tokens, like we saw you could do with GDB as well. So this is another example of integration.
Yeah. So we are on these kind of things now. We are looking into parasiting other programs and incorporating lip-poking them. So they do all the boring work, and we do the fun one. OK.
So what's the current status of the program? We just released the Poke 3.0 a few days ago. Up to now, we were doing one major release every year. And we had a maintenance branch. But people are not happy. Why? Because it was too long.
And the difference between Poke 2 and Poke 3, it was too big. It was too much. And actually, we released the Poke 2.0, for example. And in two weeks, we have forgotten about it already. Because we are so happy and so excited with the main branch. So now we are committing to release two big major releases
every year. Let's see if we can actually do that. The development. We are old GNU pspots, right? So we don't use GitHub or anything like that. So we use a mailing list. And you send your patch to the mailing list in unit diff
format, and so on and so on. And well, that is the website of the project. We have a Git repository, obviously. We have a mailing list, a development mailing list. We have a very nice build bot at Sourceware. Thank you very much to the Sourceware overseers.
They are doing a great job maintaining the infrastructure of many GNU programs, including Poke, and also the tool chain, GCC and glibc, and so on, for many years. And also, we have a pipeline hosted at GitLab that Bruno Heibel maintains. And I have no idea how it works.
It's not clear to me what even a pipeline is in that context. But it's green. So I guess it's good. We have a community website. It's called Pokeology. And we try to get practical information there, like how can you write your pickles, and so on.
And also, I have a blog in my website where I sometimes publish small articles with practical stuff. So how can you do, for example, implementing sparse tables using Poke, or accessing them? We want to be friendly to users.
And now we're starting now. You know, in Poke, we had in the Poke source distribution, gnu hacks poke. We had a pickles directory with a lot of pickles, like for p, for l, for door, for btf, for this, for that.
Some instructions said risk five, BPF. But this is getting crowded. And actually, some pickles are big and complex enough to actually need their own releases,
so that you can have several versions that work with the same version of Poke. So we are basically putting some of the pickles in separated packages. And that's the case of the elf pickle and the dwarf pickle. So for example, the elf pickles, now they are distributed separately. They have not made the first release yet,
but they are in the git repository. They have their own manual, you know, and so on, and the dwarf pickles as well. Those are the first ones. We want to get the peak of support, because it's a huge fat monster, that one. We want to put it also in its own package.
And also, you know, with nice manuals. I have to show you this, because it is such a pain to do it that you have to brag about it. So this is the poke manual, right? The new poke manual. And then when you install the pickles packages, like poke dwarf and poke elf, and here you
have, you know, like a nicely documented, you know, the pickles and everything, right? And the source distribution, sorry? Use man pages, not the menu. Well, well. Oh, well. We are generating man pages from the info page,
from the tech info. Yeah. Then actually, the idea is to use the elf pickle, because we are new, writing pickles, because poke is sort of new, right? So we are trying to discover our way forward,
but the poke elf pickles is sort of the canonical example. You know, we are using it that way. We are writing it very carefully, so if you want to write a complex pickle, you can look at it, you know? But, well.
And this is it. I am so sorry that I could not give you, you know, an actual taste of how this program is, but there is no time for that. And there are other videos on the internet that they have done already. But, and then, if you want to join the development, read, please read the hacking file,
because we took the effort of writing it. It's huge. It has a lot of good information, and absolutely no one reads it. So thank you very much. Thanks.