How hard would it be to make a position independent std?

i want to create an application that has 0 dlls linked to it, at least on windows.

but at the same time i still need the dlls to be loaded after the application is launched. position independence.

with these circumstances, i can optionally have code that can be loaded into memory directly, this could be great for protecting my application from reverse engineering. shellcode.

how hard would it be to basically define my own std functions, i.e swapping out the functions that are dynamically linked, with functions loaded at runtime. like WriteFile for instance. possibly i could make this my own std lib and use it with any project

this would allow me to compile my code into an exe, but 0 dlls would show up in dependency walker

0 Dlls is kinda difficult, because you would still need LoadLibrary and GetProcAddress. Assuming you have these two, the rest is trivial:

var WriteFile: *const fn(
  //args...
) void = undefined;

fn initFunctions() void{
  const module = LoadLibrary(...);
  WriteFile = GetProcAddres(module, "WriteFile") orelse unreachable;
}

pub fn main() void{
  // Make sure you init the pointers before using them
  initFunctions();
}

I did some searching … hope it helps
I’m fairly sure that you still have to link to kernel32.dll and ntdll.dll

How to link against static msvc libc on Windows?

Prefer depending on NtDll rather than kernel32 or other higher level DLLs

those functions need that api though right

Just FIY, doing this won’t help your with security at all. Dependency Walker also keeps track of modules loaded at runtime, and in reverse engineering, it is trivial to se what modules are loaded and to break on a cross module call.

1 Like

zigs goal is to be portable and dependency-less correct? why wasn’t position independence ever considered, with that, you can have the up most power over the system

nah, i know, but it will unlock the possibility of making compilation available as shellcode, i know i can load the pe into memory but that’s more of a overhead

You can enable position-independence in the build system.
But this has nothing to do with loading DLLs. The DLL has to be position independent, but an executable may or may not be position independent, and this has no effect on it loading modules.

but, that won’t allow me to use my application as shellcode though?

like is there any solution to this problem? i think ive seen it done before

You can create position independent code by passing the -fPIC parameter when building, or by setting .pic = true in your build.zig options.

By the way, welcome to ziggit :slight_smile:

if that works, how can i compile it into shellcode (windows). i know i start with zig build object, or object in build.zig

preferably, i need the actual shellcode in a file so i can include_bytes! in rust to test it

im trying out shellcode crafting on zig

Sorry, I don’t understand what you expect.


An example with -fPIE (position independent executable).

This a program that displays the address of main.

test.zig:

const std = @import("std");

pub fn main() void {
    std.debug.print("main={x}\n", .{&main});
}

Compile with: zig build-exe test.zig
Running ./test gives the same output, every time.

Compile with: zig build-exe -fPIE test.zig
Running ./test gives a different address for main, every time.

I think he’s looking to create position-independent code that does not rely on relocation. Just load it into memory and it’ll work (like shellcode). As far as I know that’s not possible with modern CPUs.

load the pe into memory?

i guess ill just use this as my final goal is to harden my app Oreans Technologies : Software Security Defined.

Implement your own LoadLibrary(), basically. Do your own dynamic linking and relocation. It’s not crazy hard.

examples? also will direct syscalls work, not sure if there’s a nt function for libloading

Here’s some code I wrote years ago. The function loads and statically links a .obj file so it’s not completely applicable to your use case. But it should give you some idea on what’s involved.