| Thread overview | ||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
July 13, 2014 SImple C++ code to D | ||||
|---|---|---|---|---|
| ||||
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 Re: SImple C++ code to D | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Alexandre | 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 Re: SImple C++ code to D | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Alexandre | 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 Re: SImple C++ code to D | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Alexandre | 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 Re: SImple C++ code to D | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Marc Schütz | Marc Schütz:
> Better use `ubyte[0x800] image` here. `char[]` is only for UTF-8 strings.
Right, sorry.
Bye,
bearophile
| |||
July 14, 2014 Re: SImple C++ code to D | ||||
|---|---|---|---|---|
| ||||
Posted in reply to bearophile | 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 Re: SImple C++ code to D | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Alexandre | 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 Re: SImple C++ code to D | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Alexandre | 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 Re: SImple C++ code to D | ||||
|---|---|---|---|---|
| ||||
Posted in reply to bearophile | 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 Re: SImple C++ code to D | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Alexandre | Look at line 114 of my code: http://dpaste.com/3B5WYGV Have a more better way to make this conversion ? *(DWORD*)"PE\0\0" ? | |||
Copyright © 1999-2021 by the D Language Foundation
Permalink
Reply