// Producing PE imports by building the data yourself.
// This works.
#include <stddef.h> // offsetof
#pragma data_seg(".idata$2") // special value
// page of code at 0x1000
// idata at 0x2000
// page of relocs at 0x3000 for now
// If you use /Zi, change to 0x2000 to account for .rdata
#define BASE 0x2000
typedef struct { int names, timestamp, forwarder, name, pointers; } import_t;
typedef struct { union { int offset; int (__cdecl* p)(const char*, ...); } printf; int end; } msvcrt_t;
typedef struct {
char msvcrt[sizeof("msvcrt.dll")];
char printf[sizeof("\0\0printf")]; // first two bytes are "hint"
} strings_t;
typedef struct {
import_t imsvcrt, inull;
struct { msvcrt_t names, pointers; } msvcrt;
strings_t strings;
} imports_t;
#define OFFSET(x) (offsetof(imports_t, x) + BASE)
imports_t imports = {
{ OFFSET(msvcrt.names), 0, 0, OFFSET(strings.msvcrt), OFFSET(msvcrt.pointers) }, { 0 },
{ { OFFSET(strings.printf), 0 }, { OFFSET(strings.printf), 0 } }, // msvcrt names and pointers
{ "msvcrt.dll", "\0\0printf" }
} ;
void Entry()
{
imports.msvcrt.pointers.printf.p("hello\n");
}
// cl -Ox 1.c -link -nod -entry:Entry -subsystem:console -opt:ref
No comments:
Post a Comment