Jump to page: 1 24  
Page
Thread overview
SImple C++ code to D
Jul 13, 2014
Alexandre
Jul 13, 2014
John Colvin
Jul 13, 2014
bearophile
Jul 13, 2014
Marc Schütz
Jul 13, 2014
bearophile
Jul 14, 2014
Alexandre
Jul 14, 2014
Ali Çehreli
Jul 14, 2014
bearophile
Jul 14, 2014
Alexandre
Jul 14, 2014
Alexandre
Jul 14, 2014
Alexandre
Jul 14, 2014
bearophile
Jul 14, 2014
Andrea Fontana
Jul 14, 2014
Alexandre
Jul 14, 2014
bearophile
Jul 14, 2014
Alexandre
Jul 14, 2014
bearophile
Jul 14, 2014
Alexandre
Jul 14, 2014
bearophile
Jul 14, 2014
bearophile
Jul 14, 2014
Alexandre
Jul 14, 2014
Jason King
Jul 14, 2014
Alexandre
Jul 14, 2014
bearophile
Jul 14, 2014
Alexandre
Jul 14, 2014
bearophile
Jul 15, 2014
Alexandre
Jul 15, 2014
bearophile
Jul 15, 2014
Alexandre
Jul 15, 2014
bearophile
Jul 15, 2014
Alexandre
Jul 15, 2014
bearophile
Jul 17, 2014
Meta
Jul 17, 2014
bearophile
Jul 17, 2014
Meta
Jul 15, 2014
Ali Çehreli
July 13, 2014
I have this code in C++

//...
    char image[0x800];
//...
    auto dosh = reinterpret_cast<IMAGE_DOS_HEADER*>(&image[0]);
    dosh->e_magic = *(WORD*)"MZ";
    dosh->e_cblp = 0x90;
    dosh->e_cp = 3;
    dosh->e_cparhdr = 4;
    dosh->e_maxalloc = 0xffff;
    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 ?
July 13, 2014
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);
July 13, 2014
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 = x"b8 01 4c cd 21";
    memcpy(&image[IMAGE_DOS_HEADER.sizeof], stub.ptr, stub.length);
}


Bye,
bearophile
July 13, 2014
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.
July 13, 2014
Marc Schütz:

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

Right, sorry.

Bye,
bearophile
July 14, 2014
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"...
July 14, 2014
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

July 14, 2014
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 = x"b8 01 4c cd 21";
    memcpy(&image[IMAGE_DOS_HEADER.sizeof],
           stub.ptr, stub.length);
}


Bye,
bearophile
July 14, 2014
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 = x"b8 01 4c cd 21";
	memcpy(&image[IMAGE_DOS_HEADER.sizeof],stub.ptr, stub.length);

	std.file.write("a.exe", image);
}
July 14, 2014
Look at line 114 of my code: http://dpaste.com/3B5WYGV

Have a more better way to make this conversion ?
*(DWORD*)"PE\0\0" ?
« First   ‹ Prev
1 2 3 4