How to map machine instctions in memory and execute them? (Aka, how to create a loader)

rempas rempas at tutanota.com
Wed Jun 8 20:20:55 UTC 2022


On Monday, 6 June 2022 at 15:13:45 UTC, rempas wrote:

In case someone is wondering, I found an answer in another
forum. The code is the following:

```d
import core.stdc.stdio;
import core.stdc.string;
import core.stdc.stdlib;
import core.sys.posix.sys.mman;

void putbytes(char **code, const char *bytes) {
   uint bt;
   for (int i = 0, n; sscanf(bytes + i, "%x%n", &bt, &n) == 1; i 
+= n)
     { *(*code)++ = cast(char)bt; }
}

void putdata(char **code, char** data) {
   memcpy(*code, data, (*data).sizeof);
   *code += (*data).sizeof;
}

extern (C) void main() {
   char *data = cast(char*)mmap(null, cast(ulong)15, PROT_READ | 
PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
   strcpy(data, "Hello world!\n");

   char *code = cast(char*)mmap(null, cast(ulong)500, PROT_READ | 
PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANON, -1, 0);
   char *pos = code;

   // Call the "write" and "exit" system calls
   putbytes(&pos, "48 C7 C0 1 0 0 0");    // mov rax, 0x01     
(write syscall)
   putbytes(&pos, "48 C7 C7 1 0 0 0");    // mov rdi, 0x01     
(stdout)
   putbytes(&pos, "48 C7 C2 D 0 0 0");   // mov rdx, 13       
(string length)
   putbytes(&pos, "48 BE");                      // movabs rsi, 
data  (string address)
   putdata(&pos, &data);
   putbytes(&pos, "0F 05");                        // syscall
   putbytes(&pos, "48 C7 C0 3C 0 0 0");  // mov rax, 0x3C     
(exit syscall)
   putbytes(&pos, "0F 05");                       // syscall

   // Execute the code
   (cast(void* function())code)();
}
```


More information about the Digitalmars-d-learn mailing list