Re: SImple C++ code to D

2014-07-17 Thread Meta via Digitalmars-d-learn

On Tuesday, 15 July 2014 at 16:04:26 UTC, bearophile wrote:

Alexandre:


mapstring, Address syms;


If you don't need the key ordering then use a built-in 
associative array:


Address[string] syms;

Otherwise use a RedBlackTree from std.container.



vectorpairDWORD, Address values;
vectorpairDWORD, shared_ptrDWORD addrs;


Tuple!(DWORD, Address)[] values;
Tuple!(DWORD, DWORD*)[] addrs;

Tuple and tuple are in std.typecons.

Bye,
bearophile


For `Tuple!(DWORD, DWORD*)[] addrs;`, DWORD* is not same as 
shared_ptrDWORD. It's important to keep that in mind.


Re: SImple C++ code to D

2014-07-17 Thread Meta via Digitalmars-d-learn

On Thursday, 17 July 2014 at 13:40:20 UTC, bearophile wrote:

Meta:

For `Tuple!(DWORD, DWORD*)[] addrs;`, DWORD* is not same as 
shared_ptrDWORD. It's important to keep that in mind.


OK. How do you suggest to translate it in D?

Bye,
bearophile


I don't know. I just wanted to make sure OP knew that raw 
pointers in D are not analogous to C++ shared_ptr.


Re: SImple C++ code to D

2014-07-15 Thread bearophile via Digitalmars-d-learn

Alexandre:


RefCounted!(DWORD) addr;


I think RefCounted is for advanced usages in D :-)



template Wrap(T)
{
struct Wrap
{
T val;
this(T val){val = val;}
}
}


Simpler:

struct Wrap(T) {
T val;
this(T val_) { this.val = val_; }
}


Or just:

struct Wrap(T) { T val; }

Bye,
bearophile


Re: SImple C++ code to D

2014-07-15 Thread Alexandre via Digitalmars-d-learn

Oh!
I used the RefCounted because this:
The proposed C++ shared_ptr, which implements ref counting, 
suffers from all these faults. I haven't seen a heads up 
benchmark of shared_ptr vs mark/sweep, but I wouldn't be 
surprised if shared_ptr turned out to be a significant loser in 
terms of both performance and memory consumption.


That said, D may in the future optionally support some form of 
ref counting, as rc is better for managing scarce resources like 
file handles. Furthermore, if ref counting is a must, Phobos has 
the std.typecons.RefCounted type which implements it as a 
library, similar to C++'s shared_ptr.


I found that in this link: 
http://dlang.org/faq.html#reference-counting


On Tuesday, 15 July 2014 at 14:46:01 UTC, bearophile wrote:

Alexandre:


RefCounted!(DWORD) addr;


I think RefCounted is for advanced usages in D :-)



template Wrap(T)
{
struct Wrap
{
T val;
this(T val){val = val;}
}
}


Simpler:

struct Wrap(T) {
T val;
this(T val_) { this.val = val_; }
}


Or just:

struct Wrap(T) { T val; }

Bye,
bearophile




Re: SImple C++ code to D

2014-07-15 Thread Alexandre via Digitalmars-d-learn

I have this struct:

enum AddrType { Abs, RVA, Rel };
struct Address
{
shared_ptrDWORD addr;
AddrType type;

Address(): type(Abs) {}
Address(DWORD addr, AddrType type):
addr(shared_ptrDWORD(new DWORD(addr))), type(type) {}
Address(shared_ptrDWORD addr, AddrType type):
addr(addr), type(type) {}
Address(const Address ad):
addr(ad.addr), type(ad.type) {}
};

My problem is with default alue init...
Address(): type(Abs) {}
Address(DWORD addr, AddrType type):
addr(shared_ptrDWORD(new DWORD(addr))), type(type) {}

How to make this in D ?
I do this:

struct Address
{
RefCounted!(DWORD) addr;
AddrType type = AddrType.Abs;
this(DWORD addr, AddrType type)
{
addr(RefCounted!(DWORD)(new DWORD(addr)));
this.type = type;
}
/*Address(shared_ptrDWORD addr, AddrType type) :
addr(addr), type(type) {}
Address(const Address ad) :
addr(ad.addr), type(ad.type) {}*/
};

It's correct ?


In case for a template, when I have this:
template typename T struct Wrap {
T val;
Wrap(T val): val(val) {}
};

I maded this:
template Wrap(T)
{
struct Wrap
{
T val;
this(T val){val = val;}
}
}

PS: ( I know about identation... it's wrong here... )


Re: SImple C++ code to D

2014-07-15 Thread bearophile via Digitalmars-d-learn

Alexandre:


as rc is better for managing scarce resources like file handles.


File instances are ref counted in D. Is this useful for you?

Bye,
bearophile


Re: SImple C++ code to D

2014-07-15 Thread Alexandre via Digitalmars-d-learn

Yes yes, I will use the ref... is more safer!

I will try to re-create my logic...
btw, how is the best way to reinterpret this ??:

mapstring, Address syms;

and:
vectorpairDWORD, Address values;
vectorpairDWORD, shared_ptrDWORD addrs;

On Tuesday, 15 July 2014 at 14:55:36 UTC, bearophile wrote:

Alexandre:

as rc is better for managing scarce resources like file 
handles.


File instances are ref counted in D. Is this useful for you?

Bye,
bearophile




Re: SImple C++ code to D

2014-07-15 Thread bearophile via Digitalmars-d-learn

Alexandre:


mapstring, Address syms;


If you don't need the key ordering then use a built-in 
associative array:


Address[string] syms;

Otherwise use a RedBlackTree from std.container.



vectorpairDWORD, Address values;
vectorpairDWORD, shared_ptrDWORD addrs;


Tuple!(DWORD, Address)[] values;
Tuple!(DWORD, DWORD*)[] addrs;

Tuple and tuple are in std.typecons.

Bye,
bearophile


Re: SImple C++ code to D

2014-07-15 Thread Ali Çehreli via Digitalmars-d-learn

On 07/15/2014 07:40 AM, Alexandre wrote:

 I have this struct:

I think many short discussion threads are more efficient than a single 
long thread. Many different C++ and D concepts are making this thread 
difficult to follow for me. :)


Ali



Re: SImple C++ code to D

2014-07-14 Thread Alexandre via Digitalmars-d-learn

Look at line 114 of my code: http://dpaste.com/3B5WYGV

Have a more better way to make this conversion ?
*(DWORD*)PE\0\0 ?


Re: SImple C++ code to D

2014-07-14 Thread Alexandre via Digitalmars-d-learn
And some other strange thing is, the generate struct in PE file 
is wrong.. look at imagens...


As it should be...: http://i.imgur.com/4z1T3jF.png

And how is being generated...: http://i.imgur.com/Oysokuh.png

My actual source is that: http://dpaste.com/2TZKWF5

On Monday, 14 July 2014 at 11:55:18 UTC, Alexandre wrote:

Look at line 114 of my code: http://dpaste.com/3B5WYGV

Have a more better way to make this conversion ?
*(DWORD*)PE\0\0 ?




Re: SImple C++ code to D

2014-07-14 Thread Alexandre via Digitalmars-d-learn

I don't see much need for such aliases.

Ok, how I can reduce the number of aliaSs ?

I suggest to avoid magic constants like that 0x80, like I have 
avoided it here:

memcpy(image[IMAGE_DOS_HEADER.sizeof],


Btw, I need to start that part of code in x80


Look, that is my C++ code base: http://dpaste.com/1MMZK4R
I get a lot of problens, to convert 'strings' to UCHAR... :/


Re: SImple C++ code to D

2014-07-14 Thread Andrea Fontana via Digitalmars-d-learn

Is there any counter-indication with this:

immutable ubyte[5] stub = xb8 01 4c cd 21.representation;

?

Is it a compile time value?


On Monday, 14 July 2014 at 12:18:20 UTC, bearophile wrote:

Alexandre:


Look at line 114 of my code: http://dpaste.com/3B5WYGV


The indentations are messed up.



peh.Signature = ('\0'  8) + ('\0'  8) + ('E'  8) + 'P';


You need shifts 8, 16, 24...



alias PIMAGE_DOS_HEADER = IMAGE_DOS_HEADER*;


I don't see much need for such aliases.



auto peh = cast(PIMAGE_NT_HEADERS32)image[0x80];


I suggest to avoid magic constants like that 0x80, like I have 
avoided it here:

memcpy(image[IMAGE_DOS_HEADER.sizeof], 

Bye,
bearophile




Re: SImple C++ code to D

2014-07-14 Thread Alexandre via Digitalmars-d-learn

immutable ubyte[5] stub = xb8 01 4c cd 21.representation;


that is a Real-Mode Stub Program

On Monday, 14 July 2014 at 12:32:38 UTC, Andrea Fontana wrote:

Is there any counter-indication with this:

immutable ubyte[5] stub = xb8 01 4c cd 21.representation;

?

Is it a compile time value?


On Monday, 14 July 2014 at 12:18:20 UTC, bearophile wrote:

Alexandre:


Look at line 114 of my code: http://dpaste.com/3B5WYGV


The indentations are messed up.



peh.Signature = ('\0'  8) + ('\0'  8) + ('E'  8) + 'P';


You need shifts 8, 16, 24...



alias PIMAGE_DOS_HEADER = IMAGE_DOS_HEADER*;


I don't see much need for such aliases.



auto peh = cast(PIMAGE_NT_HEADERS32)image[0x80];


I suggest to avoid magic constants like that 0x80, like I have 
avoided it here:

memcpy(image[IMAGE_DOS_HEADER.sizeof], 

Bye,
bearophile




Re: SImple C++ code to D

2014-07-14 Thread bearophile via Digitalmars-d-learn

Andrea Fontana:


Is there any counter-indication with this:

immutable ubyte[5] stub = xb8 01 4c cd 21.representation;

?


See:
https://issues.dlang.org/show_bug.cgi?id=10454
https://issues.dlang.org/show_bug.cgi?id=5909



Is it a compile time value?


Generally you need module-level values or enums to be sure a 
value is compile-time. In this case it is probably not.


Bye,
bearophile


Re: SImple C++ code to D

2014-07-14 Thread bearophile via Digitalmars-d-learn

Alexandre:


I get a lot of problens, to convert 'strings' to UCHAR... :/


I suggest you to take a look at the D docs and understand what D 
fixed-sized arrays are, dynamic arrays, and strings (that are 
dynamic arrays).


Bye,
bearophile


Re: SImple C++ code to D

2014-07-14 Thread Alexandre via Digitalmars-d-learn

bearophile, Thanks for all help!

As I said, I'm coming from C # and C + +, I need to learn 
tricks of D language...

'm reading this book: http://ddili.org/ders/d.en/

I have a struct with union...
struct IMAGE_SECTION_HEADER
{
BYTE[8] Name;
union Misc
{
DWORD PhysicalAddress,
VirtualSize;
}
DWORD VirtualAddress,
SizeOfRawData,
PointerToRawData,
PointerToRelocations,
PointerToLinenumbers;
WORD NumberOfRelocations,
NumberOfLinenumbers;
DWORD Characteristics;
}

( the  identation is wrong here... )
Btw, my problem is, how to acess the union elements ?

I try this:
//...
scth[0].Misc.VirtualSize = 15;
//...

But, the compiler return that error:
main.d(151): Error: need 'this' for 'VirtualSize' of type 'uint'

On Monday, 14 July 2014 at 13:00:21 UTC, bearophile wrote:

Alexandre:


I get a lot of problens, to convert 'strings' to UCHAR... :/


I suggest you to take a look at the D docs and understand what 
D fixed-sized arrays are, dynamic arrays, and strings (that are 
dynamic arrays).


Bye,
bearophile




Re: SImple C++ code to D

2014-07-14 Thread bearophile via Digitalmars-d-learn

Alexandre:


BYTE[8] Name;


Generally in D field names start with a lowercase (unless you 
need them with uppercase).




Btw, my problem is, how to acess the union elements ?

I try this:
//...
scth[0].Misc.VirtualSize = 15;
//...

But, the compiler return that error:
main.d(151): Error: need 'this' for 'VirtualSize' of type 'uint'


The error message is not the best. It is saying you are not 
accessing data, just its definition. So you need to instantiate 
the union:


struct Foo {
ubyte[8] name;
union Bar {
ushort physicalAddress, virtualSize;
}
Bar b;
}

void main() {
Foo f;
f.b.physicalAddress = 10;
}


Or use an anonymous one:

struct Foo {
ubyte[8] name;
union {
ushort physicalAddress, virtualSize;
}
}

void main() {
Foo f;
f.physicalAddress = 10;
}

Bye,
bearophile


Re: SImple C++ code to D

2014-07-14 Thread bearophile via Digitalmars-d-learn
Generally in D field names start with a lowercase (unless you 
need them with uppercase).


And user defined type names start with an upper case. This is 
useful, because if you write:


scth[0].Misc.virtualSize = 15;

You see immediately that Misc is not a value but a type. So it 
can't work.


Bye,
bearophile


Re: SImple C++ code to D

2014-07-14 Thread Alexandre via Digitalmars-d-learn

Yes yes, I did it, I used the anonymous type

Look the complete code: 
https://gist.github.com/bencz/3576dfc8a217a34c05a9


I know, has several things that can be improved


Re: SImple C++ code to D

2014-07-14 Thread Jason King via Digitalmars-d-learn

On Monday, 14 July 2014 at 14:50:36 UTC, Alexandre wrote:

Yes yes, I did it, I used the anonymous type

Look the complete code: 
https://gist.github.com/bencz/3576dfc8a217a34c05a9


I know, has several things that can be improved


Now that you've done that, can you build us a linker that reads 
COFF libs so we can lose optlink:)


Re: SImple C++ code to D

2014-07-14 Thread Alexandre via Digitalmars-d-learn

Soory, I not understand, why lose the optlink ?
Read the libs is simple, but, the linker do the brute force!

On Monday, 14 July 2014 at 15:17:06 UTC, Jason King wrote:

On Monday, 14 July 2014 at 14:50:36 UTC, Alexandre wrote:

Yes yes, I did it, I used the anonymous type

Look the complete code: 
https://gist.github.com/bencz/3576dfc8a217a34c05a9


I know, has several things that can be improved


Now that you've done that, can you build us a linker that reads 
COFF libs so we can lose optlink:)




Re: SImple C++ code to D

2014-07-14 Thread bearophile via Digitalmars-d-learn

Alexandre:

Look the complete code: 
https://gist.github.com/bencz/3576dfc8a217a34c05a9


I know, has several things that can be improved


memcpy(dosh.e_magic, MZ.ptr, 2);
memcpy(peh.Signature, PE\0\0.ptr, 4);
memcpy(scth[1].Name.ptr, .idata.ptr, 6);
memcpy(scth[2].Name.ptr, .data.ptr, 5);
memcpy(image[0x428], x3820.ptr, 2);
memcpy(image[0x430], x3820.ptr, 2);
memcpy(image[0x43a], printf.ptr, 6);
memcpy(image[0x448], msvcrt.dll.ptr, 10);
memcpy(image[0x201], x00304000.ptr, 4);
memcpy(image[0x207], x30204000.ptr, 4);
memcpy(image[0x600], hello\n.ptr, 6);

Instead of this very bug-prone code, write yourself a little 
function to perform this more safely.


Bye,
bearophile


Re: SImple C++ code to D

2014-07-14 Thread Alexandre via Digitalmars-d-learn

void InjectData(T)(ref T BaseSrc, string data)
{
memcpy(BaseSrc, data.ptr, data.length);
}

It's possible to improve this function ?

On Monday, 14 July 2014 at 15:45:19 UTC, bearophile wrote:

Alexandre:

Look the complete code: 
https://gist.github.com/bencz/3576dfc8a217a34c05a9


I know, has several things that can be improved


memcpy(dosh.e_magic, MZ.ptr, 2);
memcpy(peh.Signature, PE\0\0.ptr, 4);
memcpy(scth[1].Name.ptr, .idata.ptr, 6);
memcpy(scth[2].Name.ptr, .data.ptr, 5);
memcpy(image[0x428], x3820.ptr, 2);
memcpy(image[0x430], x3820.ptr, 2);
memcpy(image[0x43a], printf.ptr, 6);
memcpy(image[0x448], msvcrt.dll.ptr, 10);
memcpy(image[0x201], x00304000.ptr, 4);
memcpy(image[0x207], x30204000.ptr, 4);
memcpy(image[0x600], hello\n.ptr, 6);

Instead of this very bug-prone code, write yourself a little 
function to perform this more safely.


Bye,
bearophile




Re: SImple C++ code to D

2014-07-14 Thread bearophile via Digitalmars-d-learn

Alexandre:


void InjectData(T)(ref T BaseSrc, string data)
{
memcpy(BaseSrc, data.ptr, data.length);
}

It's possible to improve this function ?


You can add some modifiers (like @nogc for dmd 2.066), and the 
name of D functions starts with a lower case.


Bye,
bearophile


SImple C++ code to D

2014-07-13 Thread Alexandre via Digitalmars-d-learn

I have this code in C++

//...
char image[0x800];
//...
auto dosh = reinterpret_castIMAGE_DOS_HEADER*(image[0]);
dosh-e_magic = *(WORD*)MZ;
dosh-e_cblp = 0x90;
dosh-e_cp = 3;
dosh-e_cparhdr = 4;
dosh-e_maxalloc = 0x;
dosh-e_sp = 0xb8;
dosh-e_lfarlc = 0x40;
dosh-e_lfanew = 0x80;
BYTE stub[] = { 0xb8, 0x01, 0x4c, 0xcd, 0x21 };
memcpy(image[0x40], stub, sizeof(stub));


I maded this in D:

module main;

import std.stdio;
import std.c.windows.windows;

struct _IMAGE_DOS_HEADER
{
WORD e_magic;
WORD e_cblp;
WORD e_cp;
WORD e_crlc;
WORD e_cparhdr;
WORD e_minalloc;
WORD e_maxalloc;
WORD e_ss;
WORD e_sp;
WORD e_csum;
WORD e_ip;
WORD e_cs;
WORD e_lfarlc;
WORD e_ovno;
WORD e_res[4];
WORD e_oemid;
WORD e_oeminfo;
WORD e_res2[10];
LONG e_lfanew;
}
alias IMAGE_DOS_HEADER = _IMAGE_DOS_HEADER;
alias PIMAGE_DOS_HEADER = _IMAGE_DOS_HEADER*;

char image[0x800];

void main(string[] args)
{
auto dosh = cast(IMAGE_DOS_HEADER*)image[0];
//dosh.e_magic = 0x5A4D;
dosh.e_magic = cast(WORD*)(MZ);

auto stub = [0xb8, 0x01, 0x4c, 0xcd, 0x21];
dmemcpy(image[0x40], stub, stub.sizeof);
}

void * dmemcpy ( void * destination, const void * source, size_t 
num ) pure nothrow

{
(cast(ubyte*)destination)[0 ..
num][]=(cast(const(ubyte)*)source)[0 .. num];
return destination;
}

But I got errors in this:
dmemcpy(image[0x40], stub, stub.sizeof);

and in the cast of MZ to Word*
How is the best way to solve this ?


Re: SImple C++ code to D

2014-07-13 Thread John Colvin via Digitalmars-d-learn

On Sunday, 13 July 2014 at 18:48:01 UTC, Alexandre wrote:

dosh.e_magic = cast(WORD*)(MZ);


should be:

dosh.e_magic = cast(WORD*)(MZ.ptr);


Re: SImple C++ code to D

2014-07-13 Thread bearophile via Digitalmars-d-learn

Alexandre:


WORD e_res[4];


In D it's better to write:

WORD[4] e_res;



char image[0x800];


Note this is a thread-local variable. If you need a module-local 
variable you have to write:


__gshared char[0x800] image;



void main(string[] args)


If you don't need the args, then write:

void main()

In D we usually indent using 4 spaces.



auto dosh = cast(IMAGE_DOS_HEADER*)image[0];


Perhaps better (untested):

auto dosh = cast(IMAGE_DOS_HEADER*)image.ptr;




dosh.e_magic = cast(WORD*)(MZ);


Try (assuming word is 2 bytes long):

dosh.e_magic = cast(WORD*)MZ.ptr;




auto stub = [0xb8, 0x01, 0x4c, 0xcd, 0x21];


Try to use:

immutable ubyte[5] stub = [0xb8, 0x01, 0x4c, 0xcd, 0x21];




dmemcpy(image[0x40], stub, stub.sizeof);
}

void * dmemcpy ( void * destination, const void * source, 
size_t num ) pure nothrow

{
(cast(ubyte*)destination)[0 ..
num][]=(cast(const(ubyte)*)source)[0 .. num];
return destination;
}


In D most cases you can avoid to use void as argument type.
Also try to minimize the use of casts.
And in D the * of pointers is written on the left, so you write 
int* p and not int *p.
Also in that function you don't mutate num, so put a in 
before size_t.




But I got errors in this:
dmemcpy(image[0x40], stub, stub.sizeof);


What errors?

Your code with some changes, but more improvements are possible 
(untested):



import std.stdio;
import core.stdc.string;
import std.c.windows.windows;

struct IMAGE_DOS_HEADER {
WORD e_magic,
 e_cblp,
 e_cp,
 e_crlc,
 e_cparhdr,
 e_minalloc,
 e_maxalloc,
 e_ss,
 e_sp,
 e_csum,
 e_ip,
 e_cs,
 e_lfarlc,
 e_ovno;
WORD[4] e_res;
WORD e_oemid;
WORD e_oeminfo;
WORD[10] e_res2;
LONG e_lfanew;
}

alias PIMAGE_DOS_HEADER = IMAGE_DOS_HEADER*;

__gshared char[0x800] image;

void main() {
auto dosh = cast(IMAGE_DOS_HEADER*)image.ptr;
dosh.e_magic = cast(WORD)*MZ.ptr;

immutable stub = xb8 01 4c cd 21;
memcpy(image[IMAGE_DOS_HEADER.sizeof], stub.ptr, 
stub.length);

}


Bye,
bearophile


Re: SImple C++ code to D

2014-07-13 Thread via Digitalmars-d-learn

On Sunday, 13 July 2014 at 18:48:01 UTC, Alexandre wrote:

char image[0x800];


Better use `ubyte[0x800] image` here. `char[]` is only for UTF-8 
strings.


Re: SImple C++ code to D

2014-07-13 Thread bearophile via Digitalmars-d-learn

Marc Schütz:

Better use `ubyte[0x800] image` here. `char[]` is only for 
UTF-8 strings.


Right, sorry.

Bye,
bearophile


Re: SImple C++ code to D

2014-07-13 Thread Alexandre via Digitalmars-d-learn

Ok, thanks thanks!!!
Have a lot of thinks I need to learn

When I generate the exe file, something is wrong with this:
dosh.e_magic = cast(WORD)*MZ.ptr;

When the PE file is generate in EXE have just the M of MZ...


Re: SImple C++ code to D

2014-07-13 Thread Ali Çehreli via Digitalmars-d-learn

On 07/13/2014 05:21 PM, Alexandre wrote:

Ok, thanks thanks!!!
Have a lot of thinks I need to learn

When I generate the exe file, something is wrong with this:
dosh.e_magic = cast(WORD)*MZ.ptr;

When the PE file is generate in EXE have just the M of MZ...


You put the * outside the cast. bearophile had

dosh.e_magic = cast(WORD*)MZ.ptr;

However, one needs to copy the content to e_magic, which happens to be a 
WORD. The endianness may be off but it should be something like this:


import std.stdio;

void main()
{
alias WORD = ushort;
WORD w = *cast(WORD*)MZ.ptr;
writefln(%02x, w);
}

Ali



Re: SImple C++ code to D

2014-07-13 Thread bearophile via Digitalmars-d-learn

Alexandre:


When the PE file is generate in EXE have just the M of MZ...


Let's try again, is this better?


import std.c.windows.windows: WORD, LONG;

struct IMAGE_DOS_HEADER {
WORD e_magic = ('M'  8) + 'Z',
 e_cblp,
 e_cp,
 e_crlc,
 e_cparhdr,
 e_minalloc,
 e_maxalloc,
 e_ss,
 e_sp,
 e_csum,
 e_ip,
 e_cs,
 e_lfarlc,
 e_ovno;

WORD[4] e_res;
WORD e_oemid,
 e_oeminfo;

WORD[10] e_res2;
LONG e_lfanew;
}

alias PIMAGE_DOS_HEADER = IMAGE_DOS_HEADER*;

__gshared ubyte[0x800] image;

void main() {
import std.stdio;
import core.stdc.string;

auto dosh = cast(PIMAGE_DOS_HEADER)image.ptr;

immutable stub = xb8 01 4c cd 21;
memcpy(image[IMAGE_DOS_HEADER.sizeof],
   stub.ptr, stub.length);
}


Bye,
bearophile


Re: SImple C++ code to D

2014-07-13 Thread Alexandre via Digitalmars-d-learn

Oh, thanks a lot!!

With a little change all work!

look:

struct IMAGE_DOS_HEADER {
WORD e_magic,
 e_cblp,

//...

void main() {
import std.stdio;
import std.file;
import core.stdc.string;

auto dosh = cast(PIMAGE_DOS_HEADER)image.ptr;
dosh.e_magic = ('Z'  8) + 'M';

immutable stub = xb8 01 4c cd 21;
memcpy(image[IMAGE_DOS_HEADER.sizeof],stub.ptr, stub.length);

std.file.write(a.exe, image);
}